Let's suppose I have a web application that is accessed externally via http://webapp.mydomain.com and internally via http://webapp.intranetservername/
Do I need two SSL certificates? Or can the same SSL certificate be used?
You will need two SSL certificates, and the one for the intranet server will have to be self-signed, because certificate authorities are prohibited from signing certificates for internal domains (as there is no way to verify ownership of such a domain).
It is ordinarily possible to create a single SSL certificate that is valid for multiple domains (by using the Subject Alternate Name extension). However, again, a CA cannot sign one unless they can validate all of the domains it claims to be valid for.
In principle, you can have have a single certificate with two Subject Alternative Names for webapp.mydomain.com and webapp.intranetservername. In practice, that's not realistic, since no CA will issue something to .intranetservername, unless it's also a proper public domain name.
Generally speaking, if .intranetservername isn't a registered domain, no CA will issue a certificate for it, so you will have to use your own CA anyway.
If you can expect both types of clients (internally and externally) to trust your own CA, you could of course issue a certificate with two SANs with this CA.
If you expect different types of users (trusting only the default bundles of CAs or trusting your CA too), you'll have to use two certificates, one issued by each. You may also need to bind them to separate IP addresses (but availability of an extra internal IP address on a LAN isn't necessarily a problem).
More fundamentally, is there any good reason why you're calling the same web application, running on the same machine, by two distinct names, whether you access it internally or externally? Why can't people within the intranet talk to webapp.mydomain.com?
I presume this may be an attempt to increase security somehow, but if it's the same machine, it will be on both networks anyway, so I'm not sure what security improvement this name separation brings.
If you really want separate names, you could have them both on your external domain (e.g. webapp.mydomain.com and intranet.mydomain.com), and have a certificate issued by a well-known CA for both (I'm still not sure about the advantage of separating the names on the same machine, though). Indeed, certificate validation is only based on the name, and you can easily have your DNS servers point intranet.mydomain.com to a private IP address (e.g. 10.1.1.1). People from the outside won't be able to access that address, simply because it won't be routed, but it will work fine within your intranet (provided machines on the intranet are able to make DNS requests, some environments block this).
You will need two, since the SSL certification works on domain name, and you have two domain names there.
You could use the same on both, but there would be an error message displayed in most browsers warning users that the cert was not authentic.
You can get around the cost implication of having to register both with Verisign by self-certifying the intranet site, and distributing the self-cert to all of your employee browsers.
Depending on the size of the enterprise and number of users which will access "webapp.intranetservername" this may or may not be cheaper and easier than simply regging both domains with Verisign.
Related
Question on the SAN list of a certificate please.
Currently, I have a web application where mTLS, mutual TLS, two way SSL is enabled.
All my clients have the valid sets of certificates and they all pass the handshakes and are able to get the response payload when invoking my service over the web. They are all very happy.
However, as the developer, I am not able to get into my own service if mTLS is active, when running on localhost.
Hence, my immediate reaction was to ask my security team to add localhost in the SAN list.
However, they told me this is not secure and considered as bad practice to add localhost.
I tried to look at documentations online, without finding anything concrete, or that I can understand.
I do not want to disable mTLS for my local host testing. I do not want to cheat the process in anyway by deploying some sort of insecure trust.
My questions:
Why adding localhost as entry in the SAN list is considered bad practice and unsafe?
How can I test the app deployed on my localhost then?
Thank you
Why adding localhost as entry in the SAN list is considered bad practice and unsafe?
Publicly issued certificates should contain only domains which are fully controlled by the party owning the certificate. localhost is not owned by a single party and should thus not be part of a certificate issued by a public CA. But it can be part of a self-signed certificate or a certificate issued by a private, i.e. only locally trusted CA, since in this case the scope of the certificate is limited by the scope of the trust into the CA.
How can I test the app deployed on my localhost then?
It is not fully clear what exactly you want to test. But you can make your local machine appear as any domain by adding a mapping to the hosts file. This way you could access it locally by the public domain name instead of only localhost. For details see for example Adding a website to hosts file and testing it. Note that this change only affects DNS lookups on the local machine, but this is probably what you want for testing.
I'm building a site that is basically a decentralized amazon.
Basically, each seller hosts a copy of the site, at their own ip address, and accepts (bitcoin) payments using a self-hosted bitcoin wallet(https://github.com/tchoulihan/bitmerchant) that I made for this purpose.
My difficulty is this: I don't want to force every single one of these nodes to buy their own ssl, but I still need the requests to be encrypted. Would self-signed certificates work for this situation?
If they wouldn't work, what options do I have?
Edit: this is for the front-facing site, IE browser ssl.
I don't want to force every single one of these nodes to buy their own ssl
Why not? StartSSL is at least one provider that offers signed certificates for free...
Any other option that you do is going to be simply trying to reinvent SSL (and poorly at best).
Just use SSL and be done with it.
My difficulty is this: I don't want to force every single one of these nodes to buy their own ssl, but I still need the requests to be encrypted.
Join a root program, like [formally called] GeoRoot. These root programs let you become a subordinate CA so you can issue certificates for domains and subdomains that you have administrative control.
Or, point your users to CAcert or StartSSL. Both issue Class 1 end entity certificates for free. Their certificates are trusted in most desktop and mobile browsers. They charge for revocation because that's where the cost lies.
Would self-signed certificates work for this situation?
No. Browsers have moved against self signed certificates.
Related, browsers of full of these subordinate roots issued to organizations. The problem is the CA's usually certify the organizational subordinate without name constraints. The independent 3rd party auditor was removed (the RA), and the complimentary security control (name constraints) was not used. So an organization like yours could issue certificates for any domain, and not just the ones you administer. (The "inmates are running the asylum" comes to mind).
An example of such a CA is GeoTrust. An example of an unconstrained subordinate issued to an organization is Google Internet Authority G2.
A related question on Information Security Stack Exchange: Should name constraints be present on a subordinate CA issued to an organization?
And the IETF's position in the PKIX working group (bad idea): How to handle organizational subordinate CA's when I want to stop the flow of trust?.
And the IETF's position in the DBOUND working group (bad idea): Another use case to consider....
Only the CA's and Browsers think unconstrained subordinate CAs issued to an organization are a good idea.
I've been tasked with development of an intranet interface for command line software, and now I'm researching security options. Our command line application is finished, but I haven't started writing the web interface. I don't know exactly what the security requirements are for potential customers, although I believe ssh is generally acceptable for the command line interface. With this in mind, I'm asking for help developing a menu of choices with their associated pros/cons. Some day, we may consider releasing our web interface to the internet, so I'm willing to consider more security than currently necessary if it's easy and/or free.
I've been doing a lot of reading, and my tentative conclusion is that SSL security with no certificate is the best approach, not because less security is unacceptable, but because SSL is the standard and because it doesn't appear to be difficult to set up. I, a security non-expert, wouldn't need to explain why less security is acceptable to security non-experts. I could upgrade my application to use a certificate in the future if necessary.
Here's a list of SSL related security choices, sorted by my perception of security level with my comments. What level of protection do I need?
No SSL. This might be acceptable if our customers aren't worried about their employees seeing/changing each others' data. Their employees might want to share results with each other anyway, and I could use IP based access control and/or passwords for security.
Do SSL with no certificate. This encrypts the communication, which at least protects the data from being read by unauthorized employees. Using a password, this is the same level of security as ssh on the command line, right? I don't need to worry about man-in-the-middle attacks in an intranet, right? A con for this approach would be if there were loads of browser warning messages.
Do SSL with a self-signed certificate. What does this give me that no certificate gives me? If the DNS can be changed inappropriately, then the customer then my application is the least of their concerns. Worded another way, if the DNS can change, then I think ssh would be vulnerable too.
Do SSL with a local Certificate Authority. OpenSSL lets me make my own Certificate Authority. What does this give me that a self-signed certificate does not? I'm assuming that on a LAN, it's less important for the server to be verified.
Do SSL with an external Certificate Authority. Is there ever a reason to go this route for an intranet? I found some "intranet certificates" for sale online -- but it's not clear what they're offering I can't do myself.
For reference, this page might be useful for comparing certificates:
http://httpd.apache.org/docs/trunk/ssl/ssl_faq.html#aboutcerts
[update]
Here's an article discussing the risks and rules of obtaining an internal certificate from a public CA.
Yes, certificates are still useful for Intranet SSL.
There's an important difference between SSH and SSL-without-a-certificate: when you first connect to a server with SSH, your SSH stores the server's fingerprint. If you then try to connect to what the SSH client believes to be the same machine but gets back a different fingerprint, it alerts you that there might be someone intercepting your communications.
SSL-without-a-certificate, on the other hand, does not store the server's fingerprint. Your communications will still be encrypted, but if someone somehow hijacks the DNS server as you mentioned, or, as Rushyo notes, does ARP poisoning or something similar, they would be able to perform a man-in-the-middle attack. SSH, as previously mentioned, would (supposing you had connected to the correct server some time in the past) notice that the fingerprint had changed and alert you.
A self-signed certificate would be comparable in security to SSH. A man in the middle could generate their own self-signed certificate, but as long as your applications are configured to only accept that self-signed certificate, you should get an alert similar to that that SSH will give you.
A local certificate authority gives you security similar to self-signed certificates, but may be more scalable. Should you have multiple servers, each can have their own certificate, but a client only needs the top-level one to trust all of them. If a server is compromised, you can revoke its certificate rather than having to change every server's certificate.
I don't believe an external certificate authority has any advantages, other than possibly less configuration if your machines already have the certificate authority trusted.
Lastly, I don't know enough about two-factor authentication to evaluate it, but for most applications, SSL should be sufficient.
Disclaimer: I am not a security expert.
Do SSL with an external Certificate Authority. Is there ever a reason to go this route for an intranet? I found some "intranet certificates" for sale online -- but it's not clear what they're offering I can't do myself.
The benefit is that you don't need to learn how to setup your own Certificate Authority if you need to manage a decent number of certificates and/or machines. Such a certificate would already be trusted by all browsers without you needing to install your own certificates into the trusted store.
However, this is actually less secure because somebody could purchase a certificate for a different intranet and use it on your network. For this reason, SSL vendors no longer offer this service. For more information, see: https://www.godaddy.com/help/phasing-out-intranet-names-and-ip-addresses-in-ssls-6935
If you only have a very small intranet, then I would recommend using a self-signed certificate, and then just add each self-signed certificate to each computer's trusted store.
However, it quickly becomes impractical to install a new certificate on every computer in your intranet whenever you want to add a new computer. At this point, you want to setup your own Certificate Authority so that you only need to install a single CA certificate in each computer's trusted store.
Whenever I see it being talked about, it sounds like one simply 'turns on' SSL and then all requests/responses to/from an online server are magically secure.
Is that right? Is SSL just about code - can I write two apps and make them communicate via SSL, or do you have to somehow register/certificate them externally?
Secure web pages are requested on port 443 instead of the normal port 80. The SSL protocol (plenty complicated in and of itself) is responsible for securing communication, and using the certificate information on both the SERVER and the BROWSER to authenticate the server as being who they say they are.
Generating an SSL certificate is easy. Generating one that is based on the information embedded in 99% of web browsers costs money. But the technical aspects are not different.
You see, there are organizations (Verisign, Globalsign, etc...) that have had their certificate authority information INCLUDED with browsers for many years. That way, when you visit a site that has a certificate that they produced (signed), your browser says:
"well, if Verisign trusts XYZ.com, and I trust Verisign, then I trust XYZ.com"
The process is easy:
Go to a competent SSL vendor, such as GlobalSign. Create a KEY and Certificate Request on the webserver. Use them (and your credit card) to buy a certificate. Install it on the server. Point the web-browser to HTTPS (port 443). The rest is done for you.
SSL is a protocol for encrypted communications over a TCP connection (or some other reliable scheme). The encryption uses public key encryption using X.509 certificates. SSL handles both privacy and trust. These are related: if you don't trust the server, you don't believe that the server hasn't handed out its private key to everyone in North America.
Thus, the client has to trust the server's certificate. For public sites, this is arranged via a hierarchy of certificate authorities, with the root authorities trusted, automatically, by browsers and things like the JRE's socket implementation.
Anyone can generate a self-signed certificate for a server, but then the client has to be manually configured to trust it.
SSL is not, in itself, a magic bullet that makes everything secure. Security has no such things.
SSL is, however, an already-designed, ready-to-use system for solving a common problem: secure stream communication over a network connection.
There are two things you need to do to secure your application with SSL:
Modify the application's code to use SSL.
Determine the certificate trust model (and deploy and configure the application respectively).
Other answers and documentation provide better answers to how to do each of these things than I could provide.
I'll throw caution to the wind and attempt to condense an enormous subject.
SSL attempts to solve two problems:
1) Authentication and hence trust i.e can the client trust the server and vice versa
2) Communication without eavesdropping
1) Is handled by means of an intermediary i.e a trusted 3rd party - these are called 'Root Certificate Authorities' ( or Root CAs ) examples include Verisign, RSA etc
If a company wants to authenticate users and more importantly if a user wants to authenticate the company's website it's connecting to i.e your bank then the Root CA issues the company a certificate which effectively says 'I the trusted Root CA verify that I trust that Company X are who they say they are and am issuing a certificate accordingly'. So you get a chain of trust i.e I trust the certificate from ACME Co because Root CA Verisign created and issued it.
2) Once the two parties have authenticated then the certificate ( typically X590 ) is used to form a secure connection using public/private key encryption.
Hopelessly simple and incomplete but hope that gives a rough idea
Yes and no. You should self-sign a certificate and test the site with SSL internally before deploying it with SSL, first of all. To make the public site secure under SSL, you will need to purchase a certificate from one of any number of certificate providers. Then you will have a certificate signed by a trusted third party, tied to your domain name, so that users' browsers won't complain that the certificate is invalid, etc. Turning SSL on is pretty much just flipping a switch, otherwise.
For the most part you need to buy and register a certificate externally.
You need to have your server certificate signed by a Certificate Authority (CA), for which they will charge you. The client needs to trust that CA and have a copy of the relevant CA public key. The client can then check that you are who you claim to be (including domain name (from DNS) and display name for https).
This is a good tutorial on how to create self signed certificates for Apache.
If you want to know how SSL works on either the Server or the Client, then I suggest Googling it. As you suspected, it is a ridiculesly complex procedure, with lots of communication between the client and server, a lot of very peculiar math, and tons of processing. There is also a lot of theory involved, several protocols and many different algorithms and encryption standards. It's quite incredible how changing http:// to https:// is so simple to the user, but results in so much work for both sides, and is so secure. To really understand it you need to take a security course (multiple courses to fully understand it), as the entire history of encryption goes into making your login to Gmail secure.
Turning on TLS (colloquially "SSL") does not make your site magically secure. You may still be vulnerable to application-level vulnerabilities like stack overflows, SQL injection, XSS, and CSRF.
As other answers have explained, TLS only protects against a man in the middle. Traffic between a client and a properly-configured TLS server cannot be intercepted or modified, and the client can reliably confirm the identity of the server by validating the X.509 certificate. This prevents an attacker from impersonating your TLS server.
SSL actually does two things:
Encrypts the communication so that an observer seeing the data stream will not be able to read the conversation.
Guarantees that you are talking to who you think you are talking to.
It is only for #2 that you need to get official certificates. If you only care to encrypt the communication without setting up a trust relationship, you can use self-signed certificates or you can use an algorithm that does not require certificates (i.e. Diffie-Hellman).
I'm going over some client code I've inherited for doing secure communication over HTTPS, and it seems that it's not checking the common name in the server certificate (eg. 'CN = "example.com"' against the actual URL that's being requested. This is probably deliberate, since our client app is required to talk to various environments, so after contacting an initial portal (eg. example.com/main) and the user choosing an environment the app gets redirected to a specific IP, so all future requests look something like "http://127.0.0.1/page".
However being an SSL newbie, I'm unsure of the implications of disabling this check. My first reaction would be that it'd be easier to perform some kind of man-in-the-middle attack, since someone else could just copy our certificate and pretend to be one of our servers. But if we were doing common name checking you'd be able to do the same thing with custom DNS settings anyway, so it doesn't seem to actually gain us anything. Are there other attacks that this leaves us open to which we wouldn't be otherwise?
Thanks
Someone else can't just copy your certificate and use it because they don't have your private key.
If you don't check that the certificate's CN doesn't match the domain name then they can simply create their own certificate (and have it signed by a trusted CA so it looks valid), use it in place of yours, and perform a man in the middle attack.
Also, you need to be checking that the certificate comes from a trusted CA. It's the CA's job to make sure that you can only get a certificate with the CN= if you actually control that domain.
If you skip either of these checks then you are at risk of a MITM attack.
See also this answer for a different approach that will work if you have sufficient control over the client.
If you control the client code, then you can restrict the trusted CAs to just your own. Then the domain check is less important - any of your servers can pretend to be another one.
If you don't control the client code, then a cert signed by a trusted CA can be substituted for yours.
$0.02: using CN for host names is deprecated, X.509 Subject Alternate Names should be used instead.
Verifying the certificate itself and that it can be chained to a CA certificate you already trust allows you to check that the certificate is genuine and valid.
Checking the host name in the certificate allows you to check you're talking with the server you intended to talk to, provided you've verified the certificate to be valid indeed.
(Checking that the remote party is indeed the one holding the private key for that certificate is done within the SSL/TLS handshake.)
If you want an analogy with passport/ID checking for people:
Verifying the certificate is like checking that a passport or a form of ID is genuine. You can decide which forms of ID you want to accept from a person (e.g. passport, driving licence, staff card, ...) and which issuer countries you trust to be able to verify their authenticity.
Checking that the remote party is the one holding the private key is similar to checking that the picture on the passport/ID matches the face of the person in front of you.
Checking the host name is like checking the passport belongs to the person whose name is the one you're looking for.
If you don't check the host name, anyone with a valid passport that you consider genuine could come to you and claim they're the one you're looking for (by name).
In very limited set of circumstances, where you only trust a specific CA or self-signed cert where you allow any potential certificate to impersonate any other in the entire set of certificates you trust, it can be acceptable to ignore this verification, but this is very rare, and not good practice.
Checking that the name in the passport matches the name of the person you're looking for would be considered common sense; do it for certificates too. Not doing so allows anyone who has a certificate that you trust as genuine to impersonate any other certificate you would trust, thereby potentially perform MITM attacks.
The HTTPS host name verification rules are defined in RFC 2818 Section 3.1 (also more recently in a "best practices" spec, RFC 6125, not much implemented yet).
In short, the host name should be in a Subject Alternative Name DNS entry (although you can fall back on the CN of the Subject DN where there's no SAN in the certificate). When you're using an IP address, the IP address must be in a SAN IP-address entry (although some browsers will let you get away with the IP address in the CN of the Subject DN).
To do the same thing with "custom DNS settings" the attacker should exploit a DNS server (yours or a client's) to point example.com to an IP he controls, as opposed to just copying the certificate. If possible I'd create all the specific apps as subdomains of example.com and use a wildcard certificate (*.example.com) to be able to validate the CN.
Hostname verification (verifying the CN part) guarantees that the other end of the connection (server) is having a SSL Certificate issues with the domain name you typed in the address bar. Typically an attacker will not be able to get such a certificate.
If you don't verify the hostname part, somebody (somebody sit at any of the routers or proxies the request passes though) could do a man in the middle attack. Or somebody could do exploit some DNS attacks.