Tuesday, June 21, 2016

Traffic Misdirection With Redir

http://www.linux-server-security.com/linux_servers_howtos/linux_redir_commands.html

There are times when, despite your best efforts, you have little choice but to put a quick workaround in place. Reconfiguring network-border firewalls or moving services between machines is simply not an option because the network’s topology is long established and definitely shouldn’t be messed about with.
Picture the scene. You’ve lost an inbound Mail Server due to some unusual issue with the application which will probably take more than the few minutes than you have spare to fix. In their wisdom the architects of your Mail Server infrastructure didn’t separate the Web-based interface from the backend daemons which listen out for the incoming e-mail and both services reside on the server with a failed IMAP Server (Internet Message Access Protocol) which collects inbound mail for your many temperamental users.
This leaves you in a tricky position. Fundamentally you need both the services up and available. Thankfully there’s a cold-swap IMAP Server with up-to-date user configuration available but sadly you can’t move the IP Address from the E-mail Web Interface over to that box without breaking the interface’s connectivity with other services.
To save the day you ultimately rely on a smattering of lateral thinking. After all it’s only a TCP port receiving the inbound e-mail and luckily for you the Web Interface can refer to other servers so that users can access their e-mails. Step forward the excellent “redir” daemon.
This clever little daemon has the ability to listen out for inbound traffic on a particular port on a host and then forward that traffic onwards somewhere else. I should warn you in advance that it might struggle with some forms of encryption which require certificates being presented to it but otherwise I’ve had some excellent results from the redir utility. In this article we’ll look at how redirecting traffic might be able to help you out of a tight spot and additionally possible alternatives to the miniscule redir utility.

   Installation


You probably won’t be entirely surprised to read that it’s as easy as running this command on Debian derivatives:
# apt-get install redir
On Red Hat derivatives you will likely need to download it from here: http://pkgs.repoforge.org/redir/
Then you simply use “rpm -i ” where “version” is the download which you choose. For example you could do something like this:
# rpm -i redir-2.2.1-1.2.el6.rf.x86_64.rpm
Now that we have a working binary let’s look at how the useful redir utility works; thankfully it’s very straightforward indeed. Let’s begin by considering the non-encrypted version of IMAP (simply because I don’t want to promise too much with services encrypted by SSL or TLS). Have a think about the inbound e-mail server listening on TCP port 143 and what would be needed should you wish to forward traffic from that port to another IP Address first of all. This is how you could achieve that with the excellent redir utility:
# redir --laddr=10.10.10.1 --lport=143 --caddr=10.10.10.2 --cport=143
In that example we can see our broken IMAP Server (who has IP Address “10.10.10.1”) running on local port 143 (set as “--lport=”) having traffic forwarded to our backup IMAP Server (with IP Address “10.10.10.2”) to the same TCP port number.
To run redir as a daemon in the background you’re possibly safest to add an ampersand as we do in this example where instead of forwarding traffic to a remote server we simply adjust the port numbers on our local box.
# redir --laddr=10.10.10.1 --lport=143 --laddr=10.10.10.1 --cport=1234 &
You might also explore the “daemonize” command to assist. I should say that I have had mixed results from this in the past however. If you want to experiment then there’s a man page here: http://linux.die.net/man/1/daemonize
You can also use the “screen” command to open up a session and leave the command running in the background. There’s a nicely written doc on the excellent “screen” utility here from the slick Arch Linux: https://wiki.archlinux.org/index.php/GNU_Screen
The above config example scenario is an excellent way of catching visitors to a service whose clients aren’t aware of a port number change too. Say for example you have a clever daemon which can listen out for both encrypted traffic (which would usually go to TCP port 993 on IMAP for the sake of argument) and unencrypted traffic (usually TCP port 143). You could redirect traffic destined for TCP port 143 to TCP port 993 for a short period of time while you tell your users to update their software. That way you might be able to close another port on your firewall and keep things simpler.
Another life-saving use of the magical redir utility is when a DNS or IP Address changes take place.
Consider that you have a busy website listening on TCP port 80 and TCP port 443. All hell breaks loose with your ISP and you’re told that you have ten days to migrate to a new set of IP Addresses. Usually this wouldn’t be too bad but the ISP in question has set your DNS TTL expiry time (Time To Live) to a whopping seven days. This means that you need to make the move quickly to provision for the cached DNS queries which go past seven days and beyond. Thankfully the very slick redir tool can come to the rescue.
Having bound a new IP Address to a machine you simply point back at the old server IP Address using redir on your HTTP and HTTPS ports.
Then you change your DNS to reflect the new IP Address as soon as possible. The extra three days of grace should be enough to catch the majority of out-of-date DNS answers but even if it isn’t you could simply use the superb redir in the opposite direction if you ISP let you run something on the old IP Address. That way any stray DNS responses which arrive at your old server are simply forwarded to your new server. In theory (I’ve managed this in the past with a government website) you should have zero downtime throughout and if you drop any DNS queries to your new IP Address the percentage will be so negligible your users probably won’t be affected.
In case that you’re not aware the DNS caching would only affect users who had visited in the seven days prior to the change of IP Address. In other words any new users to the website would simply have the new IP Address served to them by DNS Servers, without any issue whatsoever.

   Voting By Proxy


It would be remiss not to mention that, of course IPtables also has a powerful grip on traffic hitting your boxes too. We can deploy the mighty IPtables to allow for a client to unwittingly push traffic via a conduit so that a large network can filter which websites its users are allowed to access for example.
There’s a slightly outdated document on the excellent TLDP (The Linux Documentation Project) website here: http://tldp.org/HOWTO/TransparentProxy-6.html
Incidentally Transparent Proxies are also known as Intercepting Proxies or Inline Proxies for reasons that we’ve just covered, in case it causes confusion.
With the super-natty redir tool we can create a Transparent Proxy as so:
# redir --transproxy 10.10.10.10 80 4567
In this example we are simply forwarding all traffic destined for TCP port 80 to TCP port 4567 so that the Proxy Server can filter using its rules.
There’s also a potentially useful option called “--connect” which will allow HTTP proxies with the CONNECT functionality.
To use this option add the IP Address and port of the proxy (using these options “--caddr” and “--cport” respectively).

   Shaping


I’ve expressed my reservations about the usually-very-able redir utility handling encrypted traffic because of certificates sometimes messing things up. The same applies with some other two-way communication protocols or those which open up another port such as sFTP (Secure File Transfer Protocol) or SCP (Secure Copy Protocol).
However with some experimentation if you put the redir utility to good use and you’re concerned with how much bandwidth might be forwarded then the clever redir utility can also help. Again you might have mixed results.
You can alter how much bandwidth is allowed through your redirection with this option --max_bandwidth”.
The manual in question does warn that the algorithm employed is however a basic one and can’t be expected to be entirely accurate all the time. Think of these algorithms working by their considering a period of a few seconds, the recorded throughput rate and the ceiling which you’ve set it at. When it comes to throttling and shaping bandwidth it’s not actually as easy to get a hundred percent accurate as you might first think. Even shaping with the powerful “tc” Linux tool, combined with a suitable “qdisc” for the job in hand, is prone to errors sometimes, especially when working with very low capacities of throughput, despite the fact it works on an industrial scale.

 My Network Is Down


The Traffic Control tool, “tc”, which I’ve just mentioned is also capable of simulating somewhat unusual network conditions. For example if you wanted to simulate packets being delayed in transit (you might want to test this with Pings) then you can use this “tc” command:
# tc qdisc add dev eth0 root netem delay 250ms
Append another value to the end of that command (such as “50ms”) and you then get a plus or minus variation in the delay.
You can also simulate packet loss with a command like this:
# tc qdisc change dev eth0 root netem loss 10%
This should drop ten percent of packets randomly all going well. If it doesn’t work for you then the manual can be found here: http://linux.die.net/man/8/tc and real life examples here: http://www.admin-magazine.com/Archive/2012/10
I mention the fantastic “tc” at this juncture because you might want to deploy similar settings using the versatile redir utility. It won’t offer you the packet loss functionality however it will add a random delay which might be enough to make users look at their settings and then fix their client-side config without removing all access to their service.
One option which the redir tool supports is called --random_wait”. Apparently redir will randomly multiply whatever setting you put after that option by either zero, one or two milliseconds before sending packets out. Note that this option can be used with another (the “--bufsize” option). The manual explains that it doesn’t deal directly with packets for its random delays but instead defines them as so:
“A "packet" is a block of data read in one time by redir. A "packet" size is always less than the bufsize (see also --bufsize).”
By default the buffer size is 4,096 bytes; experiment as you wish if you want to alter the throughput speeds experienced by your redirected traffic.

   IPtables Local


You can of course also use the mighty IPtables (the kernel-based firewall, Netfilter) to alter how your traffic is manipulated as it arrives at your server. Let’s consider a local port redirection and then we can have a quick a look receiving traffic to a port on one server and dutifully forwarding it onwards to another IP Address.
Here are two examples for locally redirecting.
# iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 25 -j REDIRECT --to-port 2500

# iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 443
Here we use the “PREROUTING” functionality on IPtables. The first command redirects incoming traffic for SMTP to port 2500 and the second command intercepts HTTP port traffic and forwards it onto the SSL/TLS port. The syntax isn’t too hard to follow thankfully.
If you get lost then you can easily look up any NAT (Network Address Translation) rules by using this command:
# iptables -nvL -t nat
Should you feel your blood pressure rising, get caught out and break something horribly then just flush the problematic rules away like this:
# iptables -F; iptables -t nat -F
Adding these “-F” commands to a Bash Alias is sometimes a good idea so you can recover quickly.

   IPtables Remote


What about palming off traffic to another machine by using IPtables, along the same lines that we saw with the redir utility?
Needless to say you should know what you’re doing (and experiment on a test machine ideally before trying these in production). To start us off we need to enable forwarding on our local machine (“forwarding” essentially equals “routing” to all intents and purposes, allowing traffic to move between network interfaces on a local machine). We can achieve that with this command:
# sysctl net.ipv4.ip_forward=1
If you remove the “sysctl” part and add the remainder of that command (“net.ipv4.ip_forward=1”) to the foot of the file “/etc/sysctl.conf” then that new config will survive a reboot.
Next we simply declare our rule, let’s use TCP port 80 again as our example:
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.10.10.123:80
Finally we add this line to enable masquerading:
# iptables -t nat -A POSTROUTING -j MASQUERADE
As you would expect the “-p” switch allows us to change the protocol setting from “tcp” to “udp” or “icmp”. IPtables apparently supports all of these protocols should you have the need to expand that list:
tcp, udp, udplite, icmp, esp, ah, sctp or  all

   Berners-Lee


Of course there needn’t be a reliance on tools that are, admittedly, relatively complex on occasion when other alternatives will suffice.
Since we’ve looked at a common redirect (which is required fairly frequently in my experience), namely those of Web-based services and TCP ports 80 and 443, we will briefly look at how redirects are handled internally using the world’s most popular Web Server, Apache’s httpd.
Once tested a little these rules are relatively intuitive. Here is an example of what a simple redirect would look like. You can see below that we send all inbound traffic to the HTTP port onwards to the HTTPS port:
RewriteCond %{HTTPS} !=on
In the above example if the traffic which hits this rule isn’t already using HTTPS (encrypted with SSL or TLS in other words) then the condition will assume it is unencrypted HTTP traffic and continue onwards to the next rule beneath it. The exclamation and equals sign, “!=”, meaning not-equal-to.
Imagine that you might for example want all traffic except that which is being sent by one IP Address to a new location. Note the slightly obscure exclamation mark before the IP Address “10.10.10.10” which acts as a negatory condition again, if met. You could add a whole subnet here easily too.
RewriteCond %{REMOTE_ADDR} !10.10.10.10
RewriteRule .* http://www.chrisbinnie.tld/newer_page.html [L]
This picks up all the external traffic to your Virtual Host which Apache is dutifully listening out for traffic to. If you’re curious the “[L]” flag at the end of the second line means that “mod_rewrite”, the Apache module responsible for performing the redirects, stops at that “last” command. There are a mountain of flags which the super-slick Apache can use to process its rules, for Apache 2.4 have a look here: http://httpd.apache.org/docs/2.4/rewrite/flags.html
So that “nginx” Web Server users don’t feel left out let’s have a quick look at one of its examples too. The mighty nginx has gained massive traction amongst the Web Server market, if you’re interested in one of the reasons this highly performant piece of software took such a large bite out of Apache’s market share then look up the “c10k” problem using your favourite online search device.
A simple nginx example of forwarding TCP port 80 traffic to an encrypted connection would look something like this:
if ($host = 'www.chrisbinnie.tld' ) {
            rewrite  ^/(.*)$  https://secure.chrisbinnie.tld/$1  permanent;
     }
That’s a welcome, short piece of config hopefully you agree and it also includes a look at how nginx can employ “if” statements, which is highly useful at times, and more familiar to programmers than Apache config might be.
Incidentally you need to place that config inside your “server { }” tag. There are different options to this config; I’ve seen other syntax used in nginx so if it doesn’t work then you might need to look online so that your version’s needs are met or other config isn’t breaking things. This following example is how you might alter the above to catch multiple Domain Names for instance:
server {
 listen 80;
 server_name chrisbinnie.tld www.chris.tld;
 rewrite ^ $scheme://www.chrisbinnie.tld$request_uri permanent;
...
}
Here we are simply grabbing what you might consider as malformed HTTP traffic (it’s not really malformed, users have just typed the wrong Domain Names and URLs into the Address Bar of their Browsers) and we are then forwarding it onto “www.chrisbinnie.tld” so that our precious brand remains intact.

No comments:

Post a Comment