So, is it really necessary to configure SSL/TLS when WS calls will only happen on the same machine.
No. That will not be necessary.
SSL/TLS assumes communication over an untrusted network (e.g. Internet).
If your communicating nodes (programs) are within a trusted network boundary (e.g. on the same machine), then sending encrypted messages between them will only waste your CPU cycles, and slow down communication.
[EDIT]
Also certificate verification will be useless and less secure if you need to leave the trusted network (localhost) to another to check with the CA who issued the certificate. The node/program you are talking to might as well issue a self-signed certificate which is like someone asking you to trust them because they believe themselves to be trustworthy :)
Read more here. SSL/TLS
Related
Disclaimer: I am fully aware that AES-128 is considered secure but we have wierd governmental requirements.
We run a server that provides a websocket interface with our clients as an elastic beanstalk application on AWS. It has an application load balancer in front of it which handles the HTTPS termination. We have a strange requirement on our system where all channels need to have > 200 bits encryption.
When our clients (which are IoT devices) establishes the connection the agreed on encryption becomes AES-128 (because all security policies in AWS accepts AES-128 and the devices do to).
The only way to, on the server-side, enforce AES-256 is to use the classic load balancer and add the ciphers ourselves. However, the classic load balancer does not support websocket.
Is there any possible way of circumventing this? Or do we need to add our own encryption to our channel to fulfill the requirements.
I believe that the best you could do with an Application Load Balancer (ALB) is to configure it to use the FIPS ELBSecurityPolicy-FS-1-2-Res-2020-10 security policy, however it will still be possible to negotiate ECDHE-ECDSA-AES128-GCM-SHA256 and ECDHE-RSA-AES128-GCM-SHA256. based on the table in the docs which will allow AES-128 as encryption method.
Another option would be to put an WebSocket API Gateway but the ciphers are pretty much the same and you might need to deal with the throttling in that case which is probably not the best thing to do considering the IoT clients.
Putting CloudFront in front of the ALB is not going to cut it either, as it has the same approach and the ciphers in the security policies for it are essentially the same
The security policy of the Network Load Balancer (NLB) is actually the same as the one of the ALB.
Essentially all possible AWS services are relying on the same security policies.
Which leads us to the two final options:
trying somehow to force it on client ends, which is most likely not possible
or replacing the ALB with a Network Load Balancer (which supports WebSockets) as suggested by #Mark B, setting up TCP listeners on it and handling the SSL yourself server side in your EB application which varies based on your application platform, but you should be able to enforce stricter (AES256) ciphers.
I am trying to understand an alert from Google's Security Health Analytics - "SSL_NOT_ENFORCED"
This documentation - https://cloud.google.com/sql/docs/mysql/sql-proxy states
The Cloud SQL Proxy provides secure access to your instances without the need for Authorized networks or for configuring SSL.
therefore why is SSL_NOT_ENFORCED still being alerted on? Is this just frustrating alert logic?
Of course, I wouldn't want to disable this alert just incase there ever is a Cloud SQL Proxy where there really is no SSL enforced but I would like to determine whether or not i can consider some findings as false positives.
The security center findings are there so you can understand and monitor your project's security stance. Only you can evaluate which of the findings are important to your organization. Only you can decide what actions to take to improve your security.
If you are very sure that all servers connecting to your SQL servers are private and all the connections to those servers are also private then you might be willing
to avoid the cost of SSL connections to your SQL servers.
Many security experts suggest defense in depth strategies where you deploy multiple
layers of security. In that case you would want all connections even those originating from internal servers to use SSL connections.
As you can see in the documentation, it’s recommended enforcing SSL/TLS connections when using public IPs, so the data is secure during transmission. If your data isn't encrypted, anyone can examine your packets and read confidential information. If for example, because of a vulnerability with any service in your network will let someone to penetrate it, this will also allow examining your packets in case you have a not encrypted connection, and that’s why the process and the recommendation are the same for private IPs. If you don’t enforce encryption connection, you will never be sure that all the internal communications are happening over https.
Since Cloud SQL can manage the certificates and SSL configuration for you the management cost for enforcing SSL connections is reduced. The performance hit is still there.
MySQL 5.7 Ubuntu 16.04 on AWS EC2
I've got replication set up over ssl using self-signed certificates. I am able to connect to the master from the slave using the mysql client with ssl-mode=VERIFY_IDENTITY. The replication is also working over ssl until I try and enable MASTER_SSL_VERIFY_SERVER_CERT to enable host name verification.
With that enabled the slave is no longer able to authenticate with the master and received io error 2026, which is just a generic ssl connection failed error. The logs are not any more helpful nor is ssldump which just shows the connection being aborted before the handshake even starts.
According to the docs:
To activate host name identity verification, add the
MASTER_SSL_VERIFY_SERVER_CERT option.
and
For a replication connection, specifying
MASTER_SSL_VERIFY_SERVER_CERT=1 corresponds to setting
--ssl-mode=VERIFY_IDENTITY
But also
Host name identity verification does not work with self-signed
certificates.
https://dev.mysql.com/doc/refman/5.7/en/replication-solutions-encrypted-connections.html
So how can I enable host name verification during replication with self-signed certificates? The docs seem to indicate it is impossible, but then why am I able to connect via the client with ssl-mode=VERIFY_IDENTITY?
Thank you.
The solution was to add MASTER_SSL_CA, MASTER_SSL_CERT, and MASTER_SSL_KEY to my CHANGE MASTER TO statement to manually point to the ca, cert, and key rather an trusting mysql to read them from the config.
As far as I can tell this means the mysql docs are wrong.
They state that the paths can be set in the [client] section of my.cnf, but this is clearly not the case, at least for me. For whatever reason the [client] section does appear to be used by the mysql client, but is ignored for replication.
I believe I was also misunderstanding self-signed certificates. MASTER_SSL_VERIFY_SERVER_CERT does work because I don't actually have self-signed certs, I have certs signed by my own CA. The CA cert itself is self-signed but that's different from the master/slave certs being self-signed it seems.
And finally, I was absolutely misunderstanding the purpose of MASTER_SSL_VERIFY_SERVER_CERT. It turns out I don't really need it at all because my personal CA only signs certs for this one domain anyway so there's nothing to be gained by checking that the common name of the server cert matches the requested domain. It always will. The verification would only be helpful when using a trusted certificate authority that signs certs for many domains. Then you would want to verify the certificate belongs to the domain you requested otherwise you would be vulnerable to man-in-the-middle attacks.
Hopefully that mess of info helps someone else.
I have a Go server that is currently running with Kubernetes on AWS. The website sits under a route-53 and an ELB that manages the SSL termination.
Now, I want to support HTTP/2 in my web-server in order to push resources to the clients, and I saw that HTTP/2 requires that the web-server will use HTTPS. I have a few questions according to that.
HTTP/2 requires HTTPS - In my case the HTTPS logic is in the ELB and it manages for me the SSL termination. My application gets the decrypted data as a simple HTTP request. Do I need to remove the ELB in order to enable HTTP/2 in my web-server?
Is there any way to leave the ELB there and enable HTTP/2 in my web-server?
In my local development I use openssl to generate certificate. If I deploy the web-server I need to get the CA certificate from AWS and store it somewhere in the Kubernetes certificate-manager and inject to my web-server in the initialization. What is the recommended way to do this?
I feel like I miss something, so I'll appreciate any help. Thanks
The new ELB supports HTTP/2 (https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/) but not the Push attribute (https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html#listener-configuration): “You can't use the server-push feature of HTTP/2”
If you want to use Push you can use the ELB as a level four TCP LoadBalancer and enable this at your webserver. For HaProxy it is also possible to still offset SSL/TLS with this set up (HTTP/2 behind reverse proxy) but not sure if similar is possible under ELB (probably not). This is because while HTTP/2 requires HTTPS from all the major browsers it is not a requirement of the protocol itself so load balancer -> server can be over HTTP/2 without HTTPS (called h2c).
However I would say that HTTP/2 Push is very complicated to get right - read this excellent post by Jake Archibald of Google on this: https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/. It’s generally been found to benefit in a few cases and cause no change in most and even cause degradation in performance in others. Ultimately it’s a bit of a let down in HTTP/2 features, though personally I don’t think it’s been explored enough so may be some positives to come out of it yet.
So if you don’t want Push then is there still a point in upgrading to HTTP/2 on the front end? Yes in my opinion as detailed in my answer here: HTTP2 with node.js behind nginx proxy. This also shows that there is no real need to have HTTP/2 on the backend from LB to webserver meaning you could leave it as a HTTPS offloading loaf balancer.
It should be noted that there are some use cases where HTTP/2 is slower:
Under heavy packet loss (i.e. a very bad Internet connection). Here the single TCP connection used by HTTP/2 and it’s TCP Head of Line Blocking means the connection suffers more than 6 individual HTTP/1 connections. QUIC which is a even newer protocol then HTTP/2 (so new it’s not even out yet, so not really available except on Google servers) addresses this.
For large packets due to AWS’s specific implementation. Interesting post here on that: https://medium.com/#ptforsberg/on-the-aws-application-load-balancer-http-2-support-fad4bc67b21a. This is only really an issue for truely large downloads most likely for APIs and shouldn’t be an issue for most websites (and if it is then you should optimise your website cause HTTP/2 won’t be able to help much anyway!). Could be easily fixed by upgrading the HTTP/2 window size setting but looks like ELB does not allow you to set this.
There is no benefit to deploying HTTP2 on an AWS load balancer if your backend is not HTTP2 also. Technically HTTP2 does not require HTTPS, but nobody implements HTTP2 for HTTP. HTTP2 is a protocol optimization (simple viewpoint) that removes round trips in the SSL negotiation, improves pipelining, etc. If the load balancer is communicating with your backend via HTTP, there will not be any improvement. The load balancer will see a small decrease in load due to reduced round trips during HTTPS setup.
I recommend that you configure your backend services to only use HTTPS (redirect clients to HTTPS) and use an SSL certificate. Then configure HTTP2, which is not easy by the way. You can use Let's Encrypt for SSL which works very well. You can also use OpenSSL self-signed certificates (which I don't recommend). You cannot use AWS services to create SSL certificates for your backend services, only for AWS managed services (CloudFront, ALB, etc.).
You can also setup the load balancer with Layer 4 (TCP) listeners. This is what I do when I setup HTTP2 on my backend servers. Now the entire path from client to backend is using HTTP2 without double SSL encryption / decryption layers.
One of the nice features of load balancers is called "SSL offloading". This means that you enable SSL on the load balancer and only enable HTTP on your backend web servers. This goes against HTTP2. Therefore think thru what you really want to accomplish and then design your services to meet those objectives.
Another point to consider. Since you are looking into HTTP2, at the same time remove support in your services for the older TLS versions and unsafe encryption and hashing algorithms. Dropping TLS 1.0 should be mandatory today and I recommend dropping TLS 1.1 also. Unless you really need to support ancient browsers or custom low-end hardware, TLS 1.2 should be the standard today. Your logfiles can tell you if clients are connecting via older protocols.
I looking for add support to a VPN for my software,
I known PPTP and OpenVPN , the two makes a system-wide binding, installing a TAP driver so all applications route their traffic to then.
How could i implement a VPN support for just my application ? There´s any library, example, hint or way to do it ?
My software is actually made in C++ /MFC. Using the standard CAsyncSocket.
Forwading incoming connections to your application is relatively easy:
stunnel allows you to forward traffic to specific ports through an an SSL tunnel. It requires that you run it on both ends, though.
Most decent SSH clients, such as OpenSSH or PuTTY also support port forwarding, with the added advantage that any remote SSH server can usually act as the other end of the tunnel without any modifications.
You can also use OpenVPN and other VPN solutions, but this requires specific forwarding rules to be added to the remote server.
Forwarding outgoing connections, though, is trickier without modifying your application. The proper way to do it is to implement the SOCKS protocol, preferrably SOCKS5. Alternatively, you can use an external application, such as FreeCap, to redirect any connections from your application.
After you do that, you can forward your connections to any SOCKS server. Most SSH clients, for example, allow you to use the SOCKS protocol to route outgoing connections through the remote server.
As a sidenote, OpenVPN servers do not necessarily become the default gateway for all your traffic. Some do push such a route table entry to the clients, but it can be changed. In my own OpenVPN setup I only use the VPN to access the private network and do not route everything through it.
If you can force your application to bind all outgoing sockets to one or more specific ports, you could use IP filtering rules on your system to route any connections from those ports through the VPN.
EDIT:
Tunneling UDP packets is somewhat more difficult. Typically you need a proxy process on both the remote server and the local client that will tunnel incoming and outgoing connections through a persistent TCP connection.
Your best bet would be a full SOCKS5 client implementation in your application, including the UDP-ASSOCIATE command for UDP packets. Then you will have to find a SOCKS5 proxy that supports tunnelling.
I have occasionally used Delegate which seems to be the Swiss pocket-knife of proxies. As far as I know, it supports the UDP-ASSOCIATE command in its SOCKS5 implementation and it also supports connecting two Delegate processes through a TCP connection. It is also available for both Linux and Windows. I don't remember if it can also encrypt that TCP connection, but you could always tunnel that one through stunnel or SSH if you need to.
If you have system administrator rights on a remote VPN server, however, you could probably have a simpler set-up:
Have your P2P application bind it's outgoing UDP sockets to the client VPN interface. You many need to setup a secondary default route for that interface. This way your application's outgoing packets will go through the remote server.
Have the remote server forward incoming UDP packets to specific ports through the VPN connection back to you.
This should be a simpler set-up, although if you really care about anonymity you might be interested in ensuring your P2P application does not leak DNS or other requests that can be tracked.
Put SSH connectivity in your app or use SSL. You'll have to use a protocol/service instead of VPN technology. Good luck!
I think you simply need SSL: http://www.openssl.org/
OpenVPN is based on SSL - but it is a full vpn.
The question is what do you need? If you need encryption (application private connection) - and not a vpn (virtual private network) go for ssl.
Hints can be found here:
Adding SSL support to existing TCP & UDP code?
http://sctp.fh-muenster.de/dtls-samples.html
http://fixunix.com/openssl/152877-ssl-udp-traffic.html