Archives for posts with tag: firewall

Continuing with the previous blog where we learned how to create a Jail on FreeBSD 10 without internet, here we will see two ways to provide internet access to the Jail one using PF(employing the NAT feature) and another where we piggy back a host interface(FreeBSD aliases the interface).

 

First the easy one(without NAT):

This is easy, while creating a Jail just use the host network interface and select an available IP from the same subnet as the host is on. Following is a logical representation of our setup.

Logical diagram of what we will achieve.

To start with, first determine the interface you want to use:

ifconfig

Sample output:

em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:57:37:49
inet6 fe80::a00:27ff:fe57:3749%em0 prefixlen 64 scopeid 0x1
inet 10.0.2.15 netmask 0xffffff00 broadcast 10.0.2.255

em1: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:63:4f:4b
inet 192.168.56.9 netmask 0xffffff00 broadcast 192.168.56.255
inet 192.168.56.50 netmask 0xffffffff broadcast 192.168.56.50 vhid 1
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active

On my PC em0 is the interface I would like to place my jail, as that is connected to internet.

So create a jail like:

# ezjail-admin create YOUR-jail-name ‘em0|10.0.2.16

By default ping is disabled on Jails, try using telnet to connect to one of the public websites.

In the following example I am sending a GET request on gnu.org on TCP:80(http) from the Jail, after getting its IP address:

# ezjail-admin console your-jail-name

Jail shell> host gnu.org
gnu.org has address 208.118.235.148
gnu.org mail is handled by 10 eggs.gnu.org.

Jail shell> telnet 208.118.235.148 80
Trying 208.118.235.148…
Connected to 208.118.235.148.
Escape character is ‘^]’.
GET
<!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href=”http://savannah.nongnu.org/”>here</a&gt;.</p>
<hr>
<address>Apache/2.4.7 Server at http://www.nongnu.org Port 80</address>
</body></html>
Connection closed by foreign host.

It works! 🙂

You can now install applications from internet and further configure the Jail, but first add a nameserver by creating a new /etc/resolv.conf 😉

Bonus:

We can extend on this method to attach multiple IP addresses of different networks to the jail.

dual-network

Let say you want to use both em0 and em1 with different IP addresses:

ezjail-admin create YOUR-jail-name ‘em0|10.0.2.16,em1|192.168.56.30

This attaches two new IP address to the respective interfaces and the Jail becomes accessible from both subnets(10.0.2.0/24, 192.168.56.0/24)

The above methods works if you have spare IP addresses, what if you have limited IP addresses and/or you want to isolate the Jails on a separate subnet?

Well that is when NAT comes into picture.

Read more about it at wikipedia =>

https://en.wikipedia.org/wiki/Network_address_translation

Internet connectivity for Jails with NAT(using PF):

NAT is useful when you want to isolate the jails/hosts completely on a private subnet.
And/or, you have limited public IP addresses and want to share it among different Jails.

By following this guide you will achieve something like below:

NAT-network-for-jails

 

 

 

 

 

In the above diagram the Jails are restricted to subnet 172.17.0.0/16, they cannot reach other networks on their own. In order to reach internet(or other subnets) we NAT the outgoing connection using the host as the gateway, which causes the outgoing connections to appear as originating from the host. For hosts on subnets 10. and 192. if a jail contacts them then the connection appears to come 10.0.2.15 and 192.168.56.1 respectively which is not their actual IP address!

First we need to prepare the host to act as a gateway and as router which NATs the connections(firewall/packet filtering is optional).

Enable the host system to act as a gateway:

# sysctl net.inet.ip.forwarding=1

To forward IPv6 traffic, use:

# sysctl net.inet6.ip6.forwarding=1

To enable these settings at system boot(and make them permanent), add the following to /etc/rc.conf:

gateway_enable=”YES” #for ipv4
ipv6_gateway_enable=”YES” #for ipv6

Now we create a cloned interface which the jails will user and later enable NAT using PF.

Clone the loopback interface on which the jails will communicate:

In /etc/rc.conf add:

cloned_interfaces=”lo1″

Then on the host:

# service netif cloneup

If no error is shown then lo1 is created, if you would like to confirm, run ifconfig on host.

Next create a jail with this new interface and an IP address:

# ezjail-admin create your-jail ‘lo1|172.17.1.3

Start the Jail:

# ezjail-admin onestart your-jail

If no errors are shown, your-jail is running attached to lo1, check using ifconfig:

lo1: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
inet 172.17.1.3 netmask 0xffffffff
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

However, this jail cannot reach internet, the final step is to enable NAT. I am using PF here as it is very easy to configure, configuring IPFW for NAT with stateful filtering is hard.

To enable PF add following in /etc/rc.conf:

pf_enable=”YES”

There are bunch of other things you can enable, refer the manual for these, I am trying to keep this how to simple. 😉

Next run:

# service pf start

By default PF reads the filtering rules and configuration from /etc/pf.conf. We will be making the bare minimum changes required for NAT here.

For my environment I had to add following in /etc/pf.conf:

#Declare the interfaces, Public IP, private subnet,
EXT_IF0 = “em0”
EXT_IF1 = “em1″

IP_PUB=”10.0.2.15″
NET_JAIL=”172.17.0.0/16″
LAN_IP=”192.168.56.7”
nat pass on $EXT_IF1 from $NET_JAIL to any -> $LAN_IP
nat pass on $EXT_IF0 from $NET_JAIL to any -> $IP_PUB

#### end of pf.conf ####

To make it easy to make further changes we first declare the interfaces, IP addresses the host is on($IP_PUB, $LAN_IP) and the network jails are on(NET_JAIL), you can limit NET_JAIL to a single Jail IP by using /32 as the routing prefix, like 172.17.1.3/32.

Next we have written the NAT rules, which direct PF to NAT(and pass) any packet arriving from jail network($NET_JAIL) on either of interfaces($EXT_IF0, $EXT_IF1) depending upon the destination to either the LAN($LAN_IP) or the internet($IP_PUB). PF maintains the state of the connections and the reply packets are routed back to the jails appropriately.

Done! The network diagram looks something like this:

network-diagram-NAT-network-for-jails

Refer the PF manual if you want to use more advanced features. Enjoy jailing the daemons!

Advertisements

Just a list of ideas for securing the servers.

I try to make sure that the first line of defense is not breached, if the attacker can breach that, then he is determined and can overcome any other defense you may have. Most of the “spray and pray” attacks on the internet are not that complicated and kiddies try to attack the nodes which do not patch known vulnerabilities or lack basic protection, like having easy to guess passwords.

Another point to be aware is that the more restrictive security measures we have(SELinux, etc), it may work against us, when we try to troubleshoot, implement a feature, or some software might not work etc.

Only you can decide what level of protection you need and what is at stake. Following are the absolute minimum which are highly effective, use other software(IDS, HIDS) on top of this if you can afford to spend time and effort

* Keep the server patched at regular intervals, like weekly/bi-weekly. This is very important, helps to plug any application level vulnerabilities.

* Setup a firewall allowing access to ports that are needed, like TCP:80/443 for HTTP/s, UDP:53 for DNS, etc.

* Do a netstat query on the node to check if any other services are active, either disable them permanently using /etc/rc.conf on BSD, chkconfig on CentOS, update-rc.d on Debian. Reboot the node and check whether they are disabled.

* Do not expose database services over public internet, restrict them to local network, or better yet to restrict which local IPs can connect.

* SSH access can be limited to a particular network/subnet/IP at firewall level, like only from company network, admin team, etc.

* Prefer to have non root based SSH login and then user using sudo/doas to perform actions which require root privileges.

* If direct root based SSH is required, then set “PermitRootLogin without-password” in sshd_config and restart the SSH daemon, this ensures that users having a key can connect as root. Also make sure select people have key to login as root, it makes them responsible, accountable.

* If you want to monitor the login attempts, health, use something like logwatch.

* If password based authentication is necessary to be exposed to public(which is not recommended) use a tool like fail2ban or SSHGuard. This delays the brute force attack. If the incorrect attempts are indefinitely blocked along with password expiration(+ password complexity like diceware) then brute attacks can be stopped.  As this involves many variables which can go wrong this is not recommended.

* Do not block ping unless you have experienced flood attacks, ping is necessary to troubleshoot.

The aim of having security measure is to frustrate a prospective attacker to give up, not frustrate the Admin. 😉

In India some of the IT companies, universities have restrictive firewalls and you are forced to use a proxy server which they maintain.

As a system admin/engineer you might want to connect to servers, but this will be not be possible from such networks.

Sites like youtube, gmail, etc are blocked. I have been in networks which block even technical blog sites which apparently are harmless/helpful for the company. This might not be a problem if you are using it for entertainment, but platforms like edx,make use of youtube and blocking an educational platform works against you. Blocking technical blogs does not help employees.

I am writing this post which might help you to have private access. Use the following steps at your own risk, as every company has its own policy, you might want to check it once, and if they are sane enough or have provision for exceptions, you might want to talk to them and ask them to relax the unnecessary restrictions than bypassing.

Ok,  first, we need following prerequisites:

1) A server running BSD or GNU/Linux on an external network with a public IP address.

2)  The above server running ssh on port 443.

3) SSH client + tunnel software application on your PC which is on the restricted network allowing at least 443(https). On BSD/Linux you will have openssh, proxytunnel, corkscrew, on Windows use Putty.

Without the above, the following steps in this post won’t work for you. There are multiple ways of achieving a tunnel, but the post focuses on specific way.

==Get a remote server==

You will need a remote server running ssh, you can get one from digitalocean or vultr, both of them offer VPSs with Unix-like operating systems on which you can configure ssh.

==Configure ssh to listen on port 443 on remote server==

Now that you have this server, configure ssh, which by default listens on port 22, make it to listen on both 22, 443.

In file “/etc/ssh/sshd_config”, look for line “Port 22”, and add  “Port 443”.

You will need to have:

Port 22

Port 443

Once this is edited restart the ssh daemon after checking for possible errors in the config file.

As a privileged user run “sshd -t” and fix any error it outputs, then restart the service, using “service sshd restart”. If you restart when there are errors, you risk loosing connection to the server. If necessary, check and change firewall settings to let port 443 be accessible.

==Configure and create a tunnel on FreeBSD client PC ==

Install tunneling software like proxytunnel, corkscrew, httptunnel along with openssh client.

shell> pkg install proxytunnel

Configure proxytunnel to use http proxy for connecting to the remote ssh server running on port 443. For this edit the “~/.ssh/config” file which your ssh client uses.

And add:

Host <ip_address_of_remote_server_here>

ProxyCommand proxytunnel -p http.proxy.server.here:port_number_here -d remote_server_ip_here:443

ServerAliveInterval 60  #Optional, ensures the connection stays alive when connection is not being used.

GSSAPIAuthentication no  #Optional, speeds up the authentication.

For instance it could be following,

Host 1.2.3.4

ProxyCommand proxytunnel -p proxy.example.com:8080 -d 1.2.3.4:443

What this does is, when you issue the command “ssh user@1.2.3.4” it reads the config file and applies the directives for this particular host/ip. Which in this case directs to use the “proxytunnel” command to tunnel your connection over the proxy mentioned with “-p” and to the destination mentioned using “-d“.

It works, as the remote destination is listening on port 443 and  the restrictive proxy allows 443, which now thinks that you are initiating an https connection.

With this you can now ssh to the remote host 1.2.3.4.

If you have a proxy which requires authentication, use -P option of proxytunnel, like:

ProxyCommand proxytunnel -p proxy.example.com:8080 -P user_name:password_here  -d 1.2.3.4:443

==Create a socks poxy==

When you can create a ssh connection, with openssh you can take it further to create a socks proxy which can be used by applications which support socks, like web browsers. Before following open canihazip.com in your browser and note down the ip address you currently have.

Next, from the command line on shell

“ssh -D localhost:8888 <remote_server_ip>:443”

With this ssh now listens on localhost (which is 127.0.0.1) on port 8888, all communication on this port will be passed/originate through the remote_server_ip on port 443.

Now change the proxy settings of the application to use this tunnel. With a browser set the socks proxy and open canihzip.com, your IP must be different.

Limitations:

This might not work,

If the network is using a packet analyzer and they actively block ssh packets.

If the http proxy does not support connect method.

If https is not supported over the proxy.

These are unlikely to happen, as this cripples the network access for normal usage and unless you have a paranoid admin.

An application running on client must support socks. Or you can configure a http proxy which uses socks proxy, for this you need privoxy, proxychains, polipo, etc.

Further reading:

https://wiki.archlinux.org/index.php/HTTP_tunneling

https://wiki.archlinux.org/index.php/Privoxy