initial commit

This commit is contained in:
Ste Vaidis 2022-12-14 10:24:18 +02:00
commit bf583b98d0
17 changed files with 503 additions and 0 deletions

12
LICENSE Normal file
View File

@ -0,0 +1,12 @@
Copyright (C) 2006 by Rob Landley <rob@landley.net>
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

221
README.md Normal file
View File

@ -0,0 +1,221 @@
# Port Forward Opener on OpenBSD
![Port Forward Opener](./forward_opener.png)
This setup allow external users to connect to internal servers through port forwarding.
Usefull for small offices when:
- You cannot use vpn
- You don't like port knocking
Let's say a user wants to connect to the server with RDP
1. The **User** makes a SSH connection to firewall.
2. The Firewall allows for a few seconds the IP of the user to connect to the internal server.
3. The **User** makes a RDP connection to the internal server
3. The Firewall closes SSH connection automatically.
**It's not ready for production, don't use it if you don't know exactly what you are doing**
## Addressing Scheme Example
```
[Desktop A] [Desktop B] [Desktop C]
| | |
[DSL]---[Firewall]---[Switch]---+-----+-----+-----+----+
| |
[Server] [Printer]
Address Node Port Forward
------------- ------------ ------------------------
192.168.1.1 DSL Router
192.168.1.2 Firewall WAN 22 < 60022
192.168.2.1 Firewall LAN
192.168.2.11 Desktop A 22 < 60122, 3389 < 63381
192.168.2.12 Desktop B 22 < 60222, 3389 < 63382
192.168.2.13 Desktop C 22 < 60322, 3389 < 63383
192.168.2.200 Server 3389 < 63389
192.168.2.201 Printer
```
## Dependencies
```bash
pkg_add vim dialog # nothing works properly without vim
```
## Network Settings
:floppy_disk: `vi /etc/hostname.em0`
```bash
dhcp
```
:floppy_disk: `vi /etc/hostname.stge0`
```bash
media 100baseTX
mediaopt full-duplex
inet 192.168.2.1 0xffffff00
```
:floppy_disk: `vi /etc/mygate`
```bash
192.168.1.1
```
:floppy_disk: `vi /etc/resolv.conf`
```bash
nameserver 9.9.9.9
nameserver 1.1.1.1
```
## DHCP Server
:floppy_disk: `vi /etc/dhcpd.conf`
```bash
option domain-name "taxstudio";
option domain-name-servers 9.9.9.9;
subnet 192.168.2.0 netmask 255.255.255.0 {
option routers 192.168.2.1;
range 192.168.2.11 192.168.2.19;
}
```
:floppy_disk: `vi /etc/dhcpd.interfaces`
```bash
stge0
```
Test server `dhcpd -d -c /etc/dhcpd.conf`
Start DHCP server at boot
```bash
rcctl set dhcpd flags stge0
rcctl enable dhcpd
rcctl start dhcpd
```
Show leases
```bash
cat /var/db/dhcpd.lease
```
## Firewall
Port forwarding
```bash
sysctl net.inet.ip.forwarding=1
echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf
sysctl | grep ip.forwarding
```
Rules
:floppy_disk: `vi /etc/pf.conf`
```bash
wan = em0
lan = stge0
#----------------------------------
# Defaults
#----------------------------------
pass out keep state
set skip on lo
set block-policy return
set reassemble yes
block in all
block return
match in on $wan scrub (no-df max-mss 1440)
match out on $wan scrub (random-id)
antispoof quick for { $wan lo0 }
#----------------------------------
# Input
#----------------------------------
pass quick on $lan
pass in quick proto tcp to $wan port 22 keep state
pass in quick on $lan
#----------------------------------
# Output
#----------------------------------
pass out on $lan inet keep state
#----------------------------------
# NAT
#----------------------------------
match out on $wan from !($wan) nat-to ($wan)
# Allow outgoing traffic for LAN and the gateway
pass out quick keep state
pass in on { $lan } inet
```
Enable
```bash
pfctl -d
pfctl -f /etc/pf.conf
pfctl -e
```
## Setup Opener
Start at boot and listens the port 3000
```bash
echo "/firewall/fw-server.sh" >> /etc/rc.local
```
Add Users
1. Add user to system
```bash
# fw.sh will executed on user login
useradd -d /dev/null -s /firewall/fw.sh jack
passwd jack
```
2. Add user to opener
Add one or more pf rules to user file.
```bash
vi firewall/user/jack
```
An example to allow user jack to make RDP connections to host 192.168.2.12:
`pass in proto tcp from IP to $wan port 63389 rdr-to 192.168.2.12 port 3388`
The `$wan` changes according to the address of the SSH connection that the user makes every time
## Todo
- chroot shell
- email activity

8
etc/dhcpd.conf Normal file
View File

@ -0,0 +1,8 @@
option domain-name "taxstudio.gr";
option domain-name-servers 9.9.9.9;
subnet 192.168.2.0 netmask 255.255.255.0 {
option routers 192.168.2.1;
range 192.168.2.11 192.168.2.19;
}

1
etc/dhcpd.interfaces Normal file
View File

@ -0,0 +1 @@
stge0

1
etc/hostname.em0 Normal file
View File

@ -0,0 +1 @@
dhcp

4
etc/hostname.stge0 Normal file
View File

@ -0,0 +1,4 @@
media 100baseTX
mediaopt full-duplex
inet 192.168.2.1 0xffffff00

41
etc/pf.conf Normal file
View File

@ -0,0 +1,41 @@
wan = em0
lan = stge0
#----------------------------------
# Defaults
#----------------------------------
pass out keep state
set skip on lo
set block-policy return
set reassemble yes
block in all
block return
match in on $wan scrub (no-df max-mss 1440)
match out on $wan scrub (random-id)
antispoof quick for { $wan lo0 }
#----------------------------------
# Input
#----------------------------------
pass quick on $lan
pass in quick proto tcp to $wan port 22 keep state
pass in quick on $lan
#----------------------------------
# Output
#----------------------------------
pass out on $lan inet keep state
#----------------------------------
# NAT
#----------------------------------
match out on $wan from !($wan) nat-to ($wan)
# Allow outgoing traffic for LAN and the gateway
pass out quick keep state
pass in on { $lan } inet

15
etc/rc.d/dhcpd Executable file
View File

@ -0,0 +1,15 @@
#!/bin/ksh
#
# $OpenBSD: dhcpd,v 1.3 2018/01/11 19:52:12 rpe Exp $
daemon="/usr/sbin/dhcpd"
. /etc/rc.d/rc.subr
rc_reload=NO
rc_pre() {
touch /var/db/dhcpd.leases
}
rc_cmd $1

15
etc/rc.d/sshd Executable file
View File

@ -0,0 +1,15 @@
#!/bin/ksh
#
# $OpenBSD: sshd,v 1.6 2020/01/25 12:05:08 sthen Exp $
daemon="/usr/sbin/sshd"
. /etc/rc.d/rc.subr
pexp="sshd: ${daemon}${daemon_flags:+ ${daemon_flags}} \[listener\].*"
rc_reload() {
${daemon} ${daemon_flags} -t && pkill -HUP -xf "${pexp}"
}
rc_cmd $1

93
etc/ssh/sshd_config Normal file
View File

@ -0,0 +1,93 @@
# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# override default of no subsystems
Subsystem sftp /usr/libexec/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server

1
etc/sysctl.conf Normal file
View File

@ -0,0 +1 @@
net.inet.ip.forwarding=1

40
firewall/fw-allow.sh Normal file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env ksh
#
# Forward Opener (server helper)
#
# for OpenBSD
# by ste.vaidis@gmail.com
#
if [ $# -ne 2 ]; then
logger -t "FORWARD" "fw-allow.sh executed without proper arguments: user:$1 ip:$2"
exit
fi
USER=$1
IP=$2
logger -t "FORWARD" "Open for user $USER from $IP"
cat /firewall/user/$USER | sed "s/IP/$IP/g" > /firewall/user/$USER.tmp
echo "include '/firewall/user/$USER.tmp'" >> /etc/pf.conf
if [[ $? != 0 ]]; then echo "Fail"; fi
pfctl -f /etc/pf.conf
if [[ $? != 0 ]]; then echo "Fail"; fi
sleep 15
if [[ $? != 0 ]]; then echo "Fail"; fi
sed -i "/$USER/d" /etc/pf.conf
if [[ $? != 0 ]]; then echo "Fail"; fi
pfctl -f /etc/pf.conf
if [[ $? != 0 ]]; then echo "Fail"; fi
logger -t "FORWARD" "Close for user $USER from $IP"
rm /firewall/user/$USER.tmp
exit

19
firewall/fw-server.sh Normal file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env ksh
#
# Forward Opener (server)
#
# for OpenBSD
# by ste.vaidis@gmail.com
#
/usr/local/bin/ncat -lk localhost 3000 | (
while read c; do
USER=$(echo $c | awk {'print $1'})
IP=$(echo $c | awk {'print $2'})
ps x | grep fw-allow.sh | grep $USER | grep -v grep
if [ $? -eq 1 ]; then
/firewall/fw-allow.sh $USER $IP
fi
done
)

29
firewall/fw.sh Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env ksh
#
# Let-Me-In (client)
#
# for OpenBSD
# by ste.vaidis@gmail.com
#
TITLE="OpenBSD Firewall"
USER=$(whoami)
IP=$(w | grep $USER | awk {'print $3'})
echo "$USER $IP" | nc -w1 localhost 3000 &
(
items=15
processed=0
while [ $processed -le $items ]; do
pct=$(( $processed * 100 / $items ))
echo "XXX\n"
echo "\nHello $USER from $IP"
echo "\nYou have 15 seconds to connect ($processed)"
echo "XXX"
echo "$pct"
processed=$((processed+1))
sleep 1
done
) | dialog --title "$TITLE" --gauge "\nWait please..." 10 50 0

1
firewall/user/bob Normal file
View File

@ -0,0 +1 @@
pass in log proto tcp to $wan port 60122 rdr-to 192.168.2.11 port 22

2
firewall/user/jack Normal file
View File

@ -0,0 +1,2 @@
pass in proto tcp from IP to $wan port 63389 rdr-to 192.168.2.222 port 3388
pass in proto tcp from IP to $wan port 60322 rdr-to 192.168.2.222 port 22

BIN
forward_opener.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB