My company's product allows our users to custom brand by picking a personal subdomain. We handle this with a wildcard match in nginx and then let Rails decide what to do. We require SSL everywhere and have a wildcard SSL cert, so this all works beautifully.
Now we'd like to offer custom CNAMEs, with SSL, as an add-on feature. Since we don't really want to provision hundreds of IP addresses, we'll use SNI and accept the caveats. What's the best way to setup nginx with all of these certs? We could either allow users to upload their own cert, or we could buy them for the user. Either way, how do we make nginx see them and serve them without restarts and on a large scale? Can nginx read it's config dynamically from mysql somehow, read the certificate from a script, or pass the certificate responsibility to Rails? Ideas welcome!
Related
I use Nginx to manage a lot of my web services. They listens different port, but all accessed by the reverse proxy of Nginx within one domain. Such as to access a RESTful-API server I can use http://my-domain/api/, and to access a video server I can use http://my-domain/video.
I have generated a SSL certificate for my-domain and added it into my Nginx conf so my Nginx server is HTTPS now -- But those original servers are still using HTTP.
What will happen when I visit https://my-domain/<path>? Is this as safe as configuring SSL on the original servers?
One of the goals of making sites be HTTPS is to prevent the transmitted data between two endpoints from being intercepted by outside parties to either be modified, as in a man-in-the-middle attack, or for the data to be stolen and used for bad purposes. On the public Internet, any data transmitted between two endpoints needs to be secured.
On private networks, this need isn't quite so great. Many services do run on just HTTP on private networks just fine. However, there are a couple points to take into consideration:
Make sure unused ports are blocked:
While you may have an NGINX reverse proxy listening on port 443, is port 80 blocked, or can the sites still be accessed via HTTP?
Are the other ports to the services blocked as well? Let's say your web server runs on port 8080, and the NGINX reverse proxy forwards certain traffic to localhost:8080, can the site still be accessed at http://example.com:8080 or https://example.com:8080? One way to prevent this is to use a firewall and block all incoming traffic on any ports you don't intend to accept traffic on. You can always unblock them later, if you add a service that requires that port be opened.
Internal services are accessible by other services on the same server
The next consideration relates to other software that may be running on the server. While it's within a private ecosystem, any service running on the server can access localhost:8080. Since the traffic between the reverse proxy and the web server are not encrypted, that traffic can also be sniffed, even if authorisation is required in order to authenticate localhost:8080. All a rogue service would need to do is monitor the port and wait for a user to login. Then that service can capture everything between the two endpoints.
One strategy to mitigate the dangers created by spyware is to either use virtualisation to separate a single server into logical servers, or use different hardware for things that are not related. This at least keeps things separate so that the people responsible for application A don't think that service X might be something the team running application B is using. Anything out of place will more likely stand out.
For instance, a company website and an internal wiki probably don't belong on the same server.
The simpler we can keep the setup and configuration on the server by limiting what that server's job is, the more easily we can keep tabs on what's happening on the server and prevent data leaks.
Use good security practices
Use good security best practices on the server. For instance, don't run as root. Use a non-root user for administrative tasks. For any services that run which are long lived, don't run them as root.
For instance, NGINX is capable of running as the user www-data. With specific users for different services, we can create groups and assign the different users to them and then modify the file ownership and permissions, using chown and chmod, to ensure that those services only have access to what they need and nothing more. As an example, I've often wondered why NGINX needs read access to logs. It really should, in theory, only need write access to them. If this service were to somehow get compromised, the worst it could do is write a bunch of garbage to the logs, but an attacker might find their hands are tied when it comes to retrieving sensitive information from them.
localhost SSL certs are generally for development only
While I don't recommend this for production, there are ways to make localhost use HTTPS. One is with a self signed certificate. The other uses a tool called mkcert which lets you be your own CA (certificate authority) for issuing SSL certificates. The latter is a great solution, since the browser and other services will implicitly trust the generated certificates, but the general consensus, even by the author of mkcert, is that this is only recommended for development purposes, not production purposes. I've yet to find a good solution for localhost in production. I don't think it exists, and in my experience, I've never seen anyone worry about it.
I want to ask if the configuration to have multiple SSL on one IP in Jelastic is possible with Nginx Load Balancer.
The usage is for a proxy server that will receive request from multiple custom domains.
For example:
example-proxy.com points to a Public IP address assigned to a Jelastic Jetty Application.
Now custom domains points to the Jetty Application
custom-domain-example.com CNAME www points to example-proxy.com etc.
custom-domain-example-N.org CNAME www points to example-proxy.com etc.
Is it is possible to have this kind of configuration with Jelastic?
Is this possible to be done using the existing Jelastic API? Right now what I see in the API docs is BindSSL but it seems it can only bind one, is this correct?
Yes it's possible, but you need to configure it manually (just in nginx configs) instead of using the Jelastic dashboard/API SSL feature.
The other point to remember is that because there's 1 IP per container, multiple SSL certificates can only be served via SNI. That may have implications for you depending on what browsers your users use: in most cases it's ok now (old mobile OS and Windows XP are the primary exceptions)
The BindSSL API method allows you to automatically configure one SSL certificate on the externally facing node of your environment (Nginx Load Balancer in your case). If you attempt to BindSSL multiple times you just replace the existing certificate (not add multiple certificates).
Basically this functionality was built before SNI was widely acceptable, so it was assumed 1 SSL cert. per 1 environment. You can read more about SNI to make an informed decision about whether it will suit your needs here: http://blog.layershift.com/sni-ssl-production-ready/
An alternative for your needs would be to purchase a multi-domain SSL certificate (SAN cert). This lets you contain multiple hostnames within 1 certificate. Since you mentioned that you're our customer, you can contact our SSL team for details/pricing for this option.
If you still want to use multiple SSL certs + serve them via SNI, you will probably need to use the Read and Write API methods to save the SSL certificate parts and config. file(s) on your Nginx node.
Don't forget to restart the nginx service (you can use RestartNodeById for that) after any config. changes.
EDIT: As you mentioned that your end users will have control over this process, you probably prefer to use reload instead of restart (see http://nginx.org/en/docs/beginners_guide.html#control).
You can invoke that via Jelastic API using ExecCmdById, with commandList=[{"command": "sudo service nginx reload"}]
But take care if you're allowing end users to upload their own certificates via your application - you need to ensure that what they upload is really a certificate and nothing malicious...
We have a website deployed on AWS EC2 running on ubuntu,Apache, MYSQL. We have been getting continous requestes from below IP
"195.154.105.219"
"88.150.242.243". Requesting for xmlrpc.php file using POST method. As a result our website has become really slow and our clients work has been effected. As of now we have blocked these IP values by dropping them from iptables. We would like to know how to safegaurd our site from any future attacks like this.
The question is very general, and depending to your application's requirements, your budget and other factors, there are several techniques you can use, separately or together to mitigate DDOS and SPAM attacks.
Use Auto Scaling and an Elastic Load Balancer, to let AWS scale your infrastructure depending on traffic : http://aws.amazon.com/autoscaling/
Use S3 to serve static content. S3 is designed is scaling automatically for incoming traffic. All content served by S3 directly allows to offload your EC2 based web server : http://aws.amazon.com/s3/
Use CloudFront to distribute and server your content from AWS' edge location. This mitigates DDOS by distributing attackers' request to the network of edge locations instead of sending the traffic to your web server : http://aws.amazon.com/cloudfront/
All these three options have a cost associated, be sure to understand the pricing structure before deciding to implement any of these.
If you have a relatively short and stable list of IP addresses you want to block, you can customise either your EC2 instance's Security Group (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html) either your VPC Subnet ACL (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) to deny traffic from these IP addresses. This approach is not very scalable and, most of the time, you will play a mouse / cat game trying to catchup with whatever new addresses are used by your attackers
Last but not least, using plain old Apache configuration to block certain URL or restrict access to these by IP Addresses is very effective too (http://httpd.apache.org/docs/current/en/mod/mod_authz_core.html#require and File Directive)
Last but not least, I would encourage everyone to watch this re:invent talk about DDOS resiliency for AWS : https://www.youtube.com/watch?v=V7vTPlV8P3U)
Seb
xmlrpc.php is from wordpress. install the Disable xmlrpc pingback plugin, or better yet , in the wordpress site. .htaccess , deny xmlrpc.php file ;). that will fix it. Also checkup the wp-admin/scripts for any wierd script or just . find /var/www/ -type f -mtime -10 , to find the latest modified files.. check for any wierd php script..
I have a VPS, and I am planning to run a word press instance on it. I want to host sites for different and entirely separate businesses. However, if possible we do not want to pay for a separate SSL certificate for every site.
Is this possible?
Is multisite the answer to this? Assuming that we would have to by a multi domain SSL that right?
Yes, your assumption is right. You have to get Multi domain (SAN) SSL certificate to protect your multiple domain hosted on differ servers with single certificate. It is too much expensive to get different SSL certs for individual domains, so SAN SSL is an apotheosis option.
I'm pretty new to the https world, so bear with me.
There are 2 web-servers involved:
Webserver1 has been in the organization a few years and is hosting/running multiple websites with https encryption (app1.ourcompany.com, app2.ourcompany.com, etc). It has a valid, signed certificate.
Webserver2 is a new server, for which I am responsible. I am tasked with setting up https and getting the certificate, etc. It has a web app running on it, but it does not have a domain name (only has an IP address)...which as I recently learned, is a requirement for a signed certificate.
What I'd like to know is this -- is it possible to set up a site on Webserver1 that points to the site I'm hosting on Webserver2 (ie SiteOnWebserver2.ourcompany.com) which also utilizes the Webserver1's signed/verified certificate?
Thanks for your time, SO gurus!
--Dan
A regular SSL certificate is valid for only a single domain name (such as app1.ourcompany.com). If this is the type of certificate currently being used then the existing SSL certificates will not work on your new server. If you did try this you would get an error in the browser saying that the site's domain name doesn't match the name in the SSL certificate.
The other option is to use a wildcard SSL certificate. These kinds of certificates are assigned to a certain parent domain (like ourcompany.com) and will work for all subdomains. This kind of certificate would work for app1.ourcompany.com, app2.ourcompany.com, as well as your SiteOnWebserver2.ourcompany.com.