Solved OpenVPN to jails

Code:
---{ datacenter } { cisco switch } ---------- [ 81.223.82.232 ] --- jails (iocage)          |--> [ 81.223.82.233 ]     webproxy
                   81.223.82.232 /29             FreeBSD 10.2            |-----------------> |--> [ 10.8.20.10 ]        DBjail
                   81.223.82.233 /29               OpenVPN                  10.8.20.10-49/29  |--> [ 10.8.20.11 ]        mailjail
                   81.223.82.234 /29             pf firewall
                   81.223.82.235 /29
                   81.223.82.236 /29
Hi there,

Above is the topology that I am trying to achieve.

I have a server hosted at a UK datacenter which has been given a pool of 5 plublic IPs.
We haven't got any firewall security from the datacenter has we tough that PF would be capable to protecting the server...

We used 1 of the 5 IPs for the FreeBSD host server (81.223.82.232) and another one for the web proxy server jail (81.223.82.233). All the other jails will use internal 10.8.20.10-49/29 IPs.

We would like to only allow ssh access from specific IPs address and only when connected via vpn. In other word, ssh admin@81.223.82.232 shouldn't work.

So far, I manged to install OpenVPN and get it to work with PF to gain access to the host.
The problem that I am having is that the host in on a public ip, so How could I deal with that?

The other problem that I have is, once I am connected to vpn, how do I access the jails as the nework subnet are different?

I'm not sure If I explained it very well so please please ask for clarification.
Bellow is what I have so far:
/etc/pf.conf
Code:
### Interfaces ###
ExtIf ="bce0"
JailIf ="lo1"

### Hosts ###
# OpenSMTPD  = "10.10.10.4"
WebProxy    = "10.8.20.11" # NEED TO BE CHANGE FOR PUBLIC IP - NOT SURE HOW

### Queues, States and Types ###
IcmpPing ="icmp-type 8 code 0"
SshQueue ="(ssh_bulk, ssh_login)"
SynState ="flags S/SA synproxy state"
#TcpState ="flags S/SA synproxy state"
TcpState ="flags S/SA modulate state"
UdpState ="keep state"

### Stateful Tracking Options (STO) ###
OpenSTO ="(max 90000, source-track rule, max-src-conn 1000, max-src-nodes 256)"
SmtpSTO ="(max   200, source-track rule, max-src-conn   10, max-src-nodes 256, max-src-conn-rate 200/30)"
SshSTO  ="(max   100, source-track rule, max-src-conn   10, max-src-nodes 100, max-src-conn-rate 100/30,  overload <BLOCKTEMP> flush global)"
WebSTO  ="(max  4096, source-track rule, max-src-conn   64, max-src-nodes 512, max-src-conn-rate 500/100, overload <BLOCKTEMP> flush global)"

### Tables ###
#table <spamd-white>
#table <BLACKLIST> persist persist "/etc/pf-files/blacklist.zone"
table <TRUSTED> persist file "/etc/pf-files/trusted.pftable"
table <BLOCKEDZONE> persist file "/etc/pf-files/blockedzones.pftable"
table <BLOCKTEMP> counters file "/etc/pf-files/fail2ban.pftable"
table <BLOCKNETS> {224.0.0.22, 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
                    169.254.0.0/16, 192.0.2.0/24, \
                    192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, \
                    169.254.0.0/16, 0.0.0.0/8, 240.0.0.0/4, 255.255.255.255/32}

################ Options ######################################################
### Misc Options
set skip on lo
set debug urgent
set block-policy drop
set loginterface $ExtIf
set state-policy if-bound
set fingerprints "/etc/pf.os"
set ruleset-optimization none

### Timeout Options
set optimization normal
set timeout { tcp.closing 60, tcp.established 7200}

################ Queueing ####################################################
# no quality of service (QOS) since QoS controls is monitored and rate shaped by the VPS data centre.

################ Normalization ###############################################
# set-tos 0x1c is Maximize-Reliability + Minimize-Delay + Maximize-Throughput
#scrub out log on $ExtIf all random-id min-ttl 15 set-tos 0x1c fragment reassemble
scrub     log on $ExtIf all reassemble tcp fragment reassemble

################ Translation #################################################
### NAT and Redirection rules are first match

# NAT all jail traffic
nat on $ExtIf from $JailIf:network  to any -> ($ExtIf)
#nat on $ExtIf from $IntIf:network   to any -> ($ExtIf)

# Hiawatha web proxy server
rdr on $ExtIf inet proto tcp from  !($ExtIf) to ($ExtIf) port https -> $WebProxy
rdr on $ExtIf inet proto tcp from  !($ExtIf) to ($ExtIf) port http  -> $WebProxy


# Openssh
#rdr on $ExtIf inet proto tcp from <TRUSTED> to ($ExtIf) port ssh -> lo0

# Unbound DNS for LAN machines
#rdr on $IntIf inet proto udp from $IntIf:network to $IntIf port domain -> lo0

# Ntpd time server for the LAN
#rdr on $IntIf inet proto udp from $IntIf:network to $IntIf port ntp -> lo0

# Anchors
nat-anchor "openvpn"
rdr-anchor "openvpn"

# DENY rogue redirection
#no rdr

################ Filtering ###################################################
# Rules are best (closest) match. Rules are optimized so external
# interface parsing is first followed by the internal interface.

### $ExtIf block abusive hosts in temp and blacklist tables
#block in quick on $ExtIf from                     <BLACKLIST> to any
block drop in log quick from { <BLOCKNETS> urpf-failed no-route } to any
block out quick on $ExtIf from any to { <BLOCKNETS> no-route }
block drop in log quick on $ExtIf proto udp from <BLOCKTEMP> to any
block drop in log quick on $ExtIf proto tcp from <BLOCKTEMP> to any port != ssh
block drop in log quick on $ExtIf proto tcp from <BLOCKEDZONE> to any port { 22 80 443 }
anchor "openvpn"

### $ExtIf default block with drop
block drop in log on $ExtIf
antispoof quick log for $ExtIf inet
block quick inet6

### $ExtIf inbound
pass in log on $ExtIf inet proto tcp  from !($ExtIf)      to $WebProxy      port https $TcpState $WebSTO
pass in log on $ExtIf inet proto tcp  from !($ExtIf)      to $WebProxy      port www   $TcpState $WebSTO
pass in quick log on $ExtIf proto tcp from <TRUSTED>      to $ExtIf         port ssh   $TcpState $SshSTO

### $ExtIf outbound
pass out log on $ExtIf inet proto tcp  from ($ExtIf) to !($ExtIf) $TcpState $OpenSTO
pass out log on $ExtIf inet proto udp  from ($ExtIf) to !($ExtIf) $UdpState $OpenSTO
pass out log on $ExtIf inet proto icmp from ($ExtIf) to !($ExtIf) $UdpState $OpenSTO
/usr/local/etc/openvpn/server.conf
Code:
# Which local IP address should OpenVPN listen on?
local 81.223.82.232

# Which TCP/UDP port should OpenVPN listen on?
port 1194

# PF firewall integration
script-security 2
setenv-safe wan bce0
up /usr/local/etc/openvpn/up.sh
down /usr/local/etc/openvpn/down.sh

# TCP or UDP server?
proto udp

# "dev tun" will create a routed IP tunnel,
dev tun

# SSL/TLS root certificate.
ca      /usr/local/etc/openvpn/keys/ca.crt
cert    /usr/local/etc/openvpn/keys/vpnserver.crt
key     /usr/local/etc/openvpn/keys/vpnserver.key  # This file should be kept secret

# Diffie hellman parameters.
dh      /usr/local/etc/openvpn/keys/dh4096.pem

# Configure server mode and supply a VPN subnet # for OpenVPN to draw client addresses from.
server 192.168.254.0 255.255.255.0

# Maintain a record of client
ifconfig-pool-persist ipp.txt

# The keepalive directive
keepalive 10 120

# "HMAC firewall" to help block DoS attacks and UDP port flooding.
tls-auth /usr/local/etc/openvpn/keys/ta.key 0 # This file is secret

# Select a cryptographic cipher.
cipher AES-256-CBC

# Enable compression on the VPN link.
comp-lzo

# The maximum number of concurrently connected clients we want to allow.
max-clients 2

# It's a good idea to reduce the OpenVPN daemon's privileges after initialization.
user nobody
group nobody

# The persist options will try to avoid accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun

# Output a short status file showing # current connections, truncated
status /var/log/openvpn/openvpn-status.log

# log messages
log         /var/log/openvpn/openvpn.log


# Set the appropriate level of log file verbosity.
verb 3
/usr/local/etc/openvpn/up.sh
Code:
#!/bin/sh

ANCHOR="openvpn"

/sbin/ifconfig ${dev} inet6 -ifdisabled

/sbin/pfctl -a ${ANCHOR} -F rules
/sbin/pfctl -a ${ANCHOR} -F nat
/sbin/pfctl -a ${ANCHOR} -f - <<EOT
nat on ${OPENVPN_wan} inet from ${dev}:network to any -> (${OPENVPN_wan}:0) port 1024:65535
pass quick on ${dev} all
pass in quick on ${OPENVPN_wan} inet proto udp from any to (${OPENVPN_wan}) port ${local_port_1}
EOT
 
The problem that I am having is that the host in on a public ip, so How could I deal with that?
Make ssh(1) listen on the internal OpenVPN IP maybe? Or let it listen on all ip's (default behavior) but block incoming connections to the ssh port in pf? Those are just 2 options.

The other problem that I have is, once I am connected to vpn, how do I access the jails as the nework subnet are different?
Well, you need to route the traffic and for this you need a router -- in your case, the fw.
 
Hi da1
Sorry for the late reply.. but as I still haven't managed to get this going, could you please give an example of the 'fw'?
DO I need to create a FreeBSD Gateway like in this tutorial?
 
Back
Top