In the previous article, I looked at how to use the clever redir utility to listen out for inbound traffic on a particular port on a host and then forward that traffic onward somewhere else. Here, I’ll briefly describe some other approaches to manipulating traffic that may suit your needs.
IPTables Local
You can, of course, 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, you can easily look up any NAT (Network Address Translation) rules with this command:
# iptables -nvL -t nat
Should you feel your blood pressure rising, 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 previously with the redir utility?
Needless to say you should know what you’re doing (and experiment on a test machine before trying this in production). To start off, we need to enable forwarding on our local machine (“forwarding” essentially equals “routing” for 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
Internal Redirects
Of course, you don’t need to rely on tools that are, admittedly, relatively complex when other alternatives will suffice.
We’ve already 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, so 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 on to the HTTPS port:
RewriteCond %{HTTPS} !=on RewriteRule ^(.*)$ https://www.chrisbinnie.tld/$1
In the above example, if the traffic that 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 to the next rule beneath it. The exclamation and equals sign (!=) mean not equal to.
You might, for example, want all traffic, except that which is being sent by a particular IP address, to go 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.
EOF
The next time an unexpected issue arises, you will now be armed with the excellent redir utility along with a smattering of IPtables rules to solve your headaches. For my purposes (short-lived port redirections), the redir utility is usually my tool of choice.
This is thanks to the fact that I tend to have IPtables running on my machines and obviously prefer to avoid breaking something which I know that works correctly (especially if the ports that I want to redirect already have holes punched through via existing IPtables rules). I really enjoy the simplicity of the excellent redir utility, too; that means there’s much less chance of typos.
We’ve only looked at a few scenarios with which traffic redirection can assist. There are many other circumstances when it could be used, especially during migrations of servers between datacenters or internal upgrades that require the renumbering of machines.
If you test that the syntax works locally first then you can rest assured that you can’t break too many production services. After all, you are pointing at what should be an already running service and simply sending some more traffic its way. Ultimately, the traffic will either be served or rejected depending on it its suitability for the daemon listening.
Learn more about essential sysadmin skills: Download the Future Proof Your SysAdmin Career ebook now.
Chris Binnie’s latest book, Linux Server Security: Hack and Defend, shows how hackers launch sophisticated attacks to compromise servers, steal data, and crack complex passwords, so you can learn how to defend against these attacks. In the book, he also talks you through making your servers invisible, performing penetration testing, and mitigating unwelcome attacks. You can find out more about DevSecOps and Linux security via his website (http://www.devsecops.cc).