-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unix-socket and proxy_protocol #482
Comments
I am not sure that sslh after nginx makes sense, but then I don' t know what proxy_protocol does. Unix sockets could definitely be added, both on receive and transmit. Do you think it would really improve performance? I somehow assumed that the kernel would be smart to not to actual TCP when connecting to localhost. |
nginx has on board a fairly powerful toolkit for repelling attacks and protecting conventional streaming tcp/ip connections and even udp. I installed sslh before nginx, it was sad, a huge number of processes in memory, communication interruptions, significantly more CPU usage... But even if you not use nginx, for example, there is load balancer with more rich functionality - for example HaProxy. What unites them is that they both know how to work with the proxy protocol. Yes, Nginx has the ability to work with stream connections and distribute them based on certificate and header data, but of course, nginx does not know everything that sslh can do, which is why I have to use sslh. But, I can't control access by IP addresses, because only 127.0.0.1 is visible in the sslh logs. On the other hand. If sslh is able not only to receive data through the proxy protocol, but also to transfer data to lower-level services, then services will also be able to see the client's real IP address. This is exactly what the proxy protocol was made for. Description of the proxy protocol: For example of implementation: apache plugin, proxy protocol implementation: |
To TCP/IP connection in within the server, takes ~1 millisecond and other resources are also wanted for TCP/IP, including busy ports.. A unix-socket connection spends several orders of magnitude less time and no other resources. But even if you do not need to save money, the organization of all services without using TCP / IP often looks more beautiful, visually and conveniently. I really hope that you will make unix-socket support. |
You definitely want to try
sslh supports transparent proxying, but I don't guess that helps. I think unix sockets isn't much work at all. I'll need to look into proxy-protocol before having an opinion, but at first sight it might be doable. |
I know about transparent proxy and have tried variants options with it, but this is not what is required, the IP addresses will still be lost.
Yes, this is a really simple proxy protocol and there are many examples of code. I write code in golang myself and in a few hours without difficulty added proxy protocol support to my applications in AWS. |
@monoflash: According to @yrutschle´s comment:
When I did some of the research getting chained transparency working, I created the following picture, to help me understanding, whats going on.: The kernel seems to use several shortcuts, avoids ingres/egress/bridging code, but uses tcp. |
My server is already using nginx as a web server. If nginx can work out of the box with tcp/ip streaming, it's stupid to ignore it, which is why nginx... In short, my goals are:
I have already configured and solved the main tasks, but the result was the loss of the real address with the inability to restore it. As well as the forced use of intermediate TCP/IP ports, instead of unix-socket. My map: I have already described why I want to abandon intermediate IP addresses, as well as the loss of real IP in the logs is not critical yet, but it is likely to lead to loss of control when attacks occur. By suggesting that you add features for working with unix-socket and proxy protocol, I wanted to make your product better. But, I've already written so many explanations that writing a my own multiplexer, replacement sslh for, in golang already seems like a more reasonable idea. And, perhaps, the number of lines of code will be commensurate with this discussion. I don't write in C language myself and I can't offer a really good pull-request, so it's up to you to decide what you'll do with my suggestion. |
So all endpoints are your own systems? Looks like only service1 and service2 are then connected via proxy-protocol? I have described one setting with nginx in front and sslh behind here:, however I moved to openresty (fork of nginx) because of the famous lua possibility. Edit: |
This causes a performance and security issue. I mentioned this earlier. It was painful for the server.
nginx has many parts, I use two, the one that is an http/https server and the one that can work with streaming tcp/ip traffic. Traffic must be forwarded between them either via unix-socket or IP. All parts of nginx understand the proxy protocol and therefore there is no problem with IP addresses.
This is not the whole config, the part with the return from the sslh https traffic is omitted. IP addresses are lost on those services that do not understand the proxy protocol - it sslh. This is not an ideal scheme, it is an economical and perfimance scheme. A rather complicated task is being solved using only nginx and sslh. The ideal scheme can be made on the basis of HAProxy. But in any case, IP addresses will be lost, because the multiplexer simply does not support them. If the configuration and schema are not clear, don't go deeper, this is a really complex and unique scheme for working on one port of more than 3 protocols with branches not only for protocol but also for HTTPS traffic and certificate. Now my with a choice, either to convince you to make a more functional multiplexer, or to change multiplexer. So far, I've accepted that IP addresses are completely lost on the multiplexer side, but everything works. |
Ok, as far, as I understand now, you are dealing with incoming pure protocol connections, your nginx is encapsulating the forwarded connection into proxy protocol. In your Incoming-stanca, the line In your to-sslh-stanca I would recommend, replacing the line: In the Http-from-sslh-stanca I see several problems: And as @yrutschle already mentioned, use sslh-ev, as with that you have not a forked process for each connection. Even, when the forwarded interprocess connections are using tcp, this is not a big performance issue. According to several performance tests it is somewhere around 15%-20% compared to unix sockets. But you have to take into consideration, that rewrapping in ha_proxy_protocol connections consumes additional ressources, while just forwarding packets is easy. So my guess is, that your performance problem just came from to many parallel forked processes and sslh-ev may help you. |
Wrong. This connection receives requests that have the proxy protocol enabled. If disable the proxy protocol at the entrance of this connection, there will be problems.
In this case, sslh does not respond to requests at all. What you suggest I've tried doesn't work!
Sure. sslh doesn't support this, so it doesn't work. A comment was left in case I forget and want to optimize in the future... To avoid hitting the wall again.
I can't disable this, then I'll start loosing real IP address not only on the multiplexer, but also on other parts, connections for which are forked and received using nginx.
I wrote that this part of the configuration is omitted so as not to "show" the domain names.
You misunderstand. The main remaining problem is the loss of real IP addresses. All your recommendations are not working and are not correct. The main problem is not to fix what is already configured, tested and working.
Even if i do everything as you suggest, to make everything work, it will not solve the problem of IP loss in the sslh and performance in any way. If don't plan to add a proxy protocol and the ability to send and receive request via a unix socket, say so. |
FYI I have opened a discussion #483 as I started implementing UNIX sockets -- it should be trivial enough. I'll look into proxy_protocol afterwards, as it is independant, but it looks fairly simple as well. Do you know of v1 is still used? From the cursory look I had, I would be more confortable implementing only v2 with binary structures. |
I'm really looking forward to the new release.
Judging by the fact that debugging my configuration, I often saw the text from the proxy protocol version 1 in the logs, it is being used. It will probably be easier for you to look into the implementation of the proxy protocol on the nginx side, I think a quick look at the code will answer all your questions:
In my development, I use this library, it is in the golang language, but golang is very similar to the C language. You can look into the files implementing version 1 and version 2, there are comments in the code, it can also help a lot. I'm looking forward to a positive decision. |
Unfortunately this answer is wrong:
What I have suggested works. If it does not work for you, you miss the corresponding settings for transparency in y<our operating system. I manage around 10 nginx configurations with this setting.
Again, this line just has no effect, as this stanca describes an incoming handler, and the
You don't lose real IP addresses if you follow the right configuration, it works!
I dissagree, as mentioned before in detail
Just set up straight transparent connections, and everything is fine.
Again NO.
Take some time and read the documents here about transparency. The nice effect is, that nginx just works line sslh on this. So my recommendation is, set up a dummy interface for sslh, configure the right routing rules just together with the interface configuration in /etc/network/interfaces, configure sslh (or sslh-ev) with transparency and you are done. I cases, where you will reconnect from sslh to nginx, the receiving unit of nginx must also be on the dummy interface. Here is one of my stripped down nginx (openresty, because of lots of lua) configurations:
You will see, that the primary stanca listens on the public ip address, while those servers, which are destinations coming from sslh or rerouted from nginx are listening on the same dummy interface, as sslh is listening. This is my dummy interface with routing rules:
and finally this line has to go to /etc/iproute2/rt_tables I know, what I am talking about. |
@FastNetMon There are no words... The question concerned the implementation of the unix socket and the proxy protocol on sslh, but you went somewhere into the forest... |
cac7f48 adds support to connect to UNIX sockets. I am not sure it covers all the corner cases (a lot of code assumes connections are IP; Ideally I'll want to do more refactor to abstract out the protocol types). It works with an entry as this:
|
bf08229 adds support for listening on Unix sockets. |
The server should definitely create and delete a unix-socket itself. This is the behavior of all properly written services. The behavior is similar to working with a TCP/IP port. |
That's fair. I complicated myself thinking about a server that would accidently try to unlink another file in case of bad configuration :-) I'll add that later today. |
for me, nginx always fail to delete the socket file. Every reboot and service restart I should delete that manually. |
On modern linux, the /run directory is located in memory to partially solve problem of reset or kill. But I can't confirm this behavior of nginx, I have the latest version of nginx, unix socket is used a lot. Backend services create and delete their own unix sockets. Nginx does not have any additional scripts for deleting unix sockets whose server is nginx. I have not tested whether the unix socket files whose server is nginx remain, but even if they do, it overwrites them on startup. I looked at the code. If I understood everything correctly, then on line 125, before creating a unix socket, nginx deletes the old one, if there is one. And this part of the code is also indicative: |
It is not possible to create a configuration that is convenient enough to use.
If you set sslh after nginx, the ip addresses are not visible in the logs, since she does not understand proxy_protocol.
If you install sslh before nginx, then the server is in serious danger, sslh performance is seriously inferior to nginx and the same problem with ip addresses.
Connectivity of services over TCP/IP is also not beneficial, as resources (ports+open file) and time (+1ms per connection are spent on connections, since sslh cannot listen and transmit over a unix socket.
If you add support proxy_protocol compatible with nginx and unix-socket to your future plans, this would solve many problems.
proxy_protocol and unix-socket would naturally be useful in all directions, both for receiving and listening and for transmitting.
Is this possible in the future?
The text was updated successfully, but these errors were encountered: