---
tags:
  - freebsd
  - homelab
---

# FreeBSD notes

## VIM

**Disable mouse**

`echo "set mouse-=a" >> ~/.vimrc`

**Mac keyboard backspace fix**

`set backspace=indent,eol,start`

## OpenSSH daemon & client

Set settings in sshd_config:

```
Banner /etc/ssh/banner.txt
```

```
#################################################################
#                   _    _           _   _                      #
#                  / \  | | ___ _ __| |_| |                     #
#                 / _ \ | |/ _ \ '__| __| |                     #
#                / ___ \| |  __/ |  | |_|_|                     #
#               /_/   \_\_|\___|_|   \__(_)                     #
#                                                               #
#  You are entering into a secured area! Your IP, Login Time,   #
#   Username has been noted and has been sent to the server     #
#                       administrator!                          #
#   This service is restricted to authorized users only. All    #
#            activities on this system are logged.              #
#  Unauthorized access will be fully investigated and reported  #
#        to the appropriate law enforcement agencies.           #
#################################################################
```

To reduce OS fingerprinting

```
VersionAddendum none
```

```
debug1: Local version string SSH-2.0-OpenSSH_8.6
debug1: Remote protocol version 2.0, remote software version OpenSSH_8.8
debug1: compat_banner: match: OpenSSH_8.8 pat OpenSSH* compat 0x04000000

instead of:

debug1: Local version string SSH-2.0-OpenSSH_8.6
debug1: Remote protocol version 2.0, remote software version OpenSSH_8.8 FreeBSD-20211221
debug1: compat_banner: match: OpenSSH_8.8 FreeBSD-20211221 pat OpenSSH* compat 0x04000000
```

## OpenSSH daemon faster connection dropping

Restricting users by not allowing explicit ssh access can improve your ssh server connections.
In the default FreeBSD `/etc/ssh/sshd_config` configuration the `MaxAuthTries` is `3`. Which means all system users can try up to 3 times before the connection is gracefull dropped. 

We will create an explicit `ssh` group to have fine control over who may login over ssh and who is directly disconnected. By enabling this, an attacker could guess user account names if there are authentication tries or not.

SSH for the root user is always a bad idea, but in some setups it is necessary. For the truely paranoid root user access can be further restricted based on IP address and ssh-key only.

The normal behaviour when ssh to a machine wil look like this even with `PermitRootLogin no` set:

```
jerry@jerrys-MacBook-Pro ~ % ssh 192.168.2.100 -lroot
Password for root@pineapple.xor-gate.org:
Password for root@pineapple.xor-gate.org:
Password for root@pineapple.xor-gate.org:
root@192.168.2.100: Permission denied (publickey,keyboard-interactive).
```

When the global `MaxAuthTries 0` and a match block is used then the connection is immediatelly dropped:

```
jerry@jerrys-MacBook-Pro ~ % ssh 192.168.2.100 -lroot
Received disconnect from 192.168.2.100 port 22:2: Too many authentication failures
Disconnected from 192.168.2.100 port 22
```

```
MaxAuthTries 0

Match Group ssh
        MaxAuthTries 3
```

## Protecting SSH with sshguard on pf

Install ssh guard

```
# pkg install sshguard
```

Modify (or create) `/etc/pf.conf` with the `sshguard`  firewall table. First we block all traffic. Also double check you don't have a rule before the SSHGuard rule that allows access.

```
ext_if = igb0

table <sshguard> persist

block all

block drop in log quick on $ext_if inet from <sshguard> to any

pass in
```

Enable pf firewall in the `rc.conf`
```
pf_enable="YES"
pf_rules="/etc/pf.conf"
```

```
# service pf reload
Reloading pf rules.
pfctl: /dev/pf: No such file or directory
```

The pf kernel device node doesn't exist so it is not loaded

```
# kldload pf
```

Or start pf using the rc script:

```
# /etc/rc.d/pf start
```

To show the blocked IPs use pfctl show and clear on the sshguard table:

```
pfctl -t sshguard -T show
pfctl -t sshguard -T flush
```

This slows down brute-force attacks:

```
Mar 25 07:44:29 pineapple sshd[87092]: Disconnecting invalid user pi 118.161.193.40 port 54511: Too many authentication failures [preauth]
Mar 25 07:45:07 pineapple sshd[87166]: error: maximum authentication attempts exceeded for root from 118.161.193.40 port 54556 ssh2 [preauth]
Mar 25 07:45:07 pineapple sshd[87166]: Disconnecting authenticating user root 118.161.193.40 port 54556: Too many authentication failures [preauth]
Mar 25 07:45:29 pineapple sshd[87808]: Invalid user oracle from 118.161.193.40 port 54563
Mar 25 07:45:29 pineapple sshd[87808]: error: maximum authentication attempts exceeded for invalid user oracle from 118.161.193.40 port 54563 ssh2 [preauth]
Mar 25 07:45:29 pineapple sshd[87808]: Disconnecting invalid user oracle 118.161.193.40 port 54563: Too many authentication failures [preauth]
Mar 25 07:45:44 pineapple sshd[88058]: Invalid user sFTPUser from 118.161.193.40 port 54598
```

See also https://forums.freebsd.org/threads/howto-set-up-and-configure-security-sshguard-pf.39196/

**Reverse shell**

* Reverse target system: `ssh -R <remote port>:<local host>:<local port> <remote host>`
* Control system: `ssh -p <remote port> localhost` 

https://jfrog.com/connect/post/reverse-ssh-tunneling-from-start-to-end/
https://moreillon.medium.com/ssh-reverse-shells-5094d9be2094

## User management

### Set default shell

For existing users, use the chsh command (“change shell”):

```
chsh -s SHELL USER
chsh -s /usr/local/bin/bash root
```
For future users:

Edit `/etc/pw.conf` defaultshell keywords
When use `adduser()`, choose necessary shell

### Add new group and add user to group

```
root@pineapple:/home/jerry # pw group add ssh
root@pineapple:/home/jerry # pw user mod jerry -G wheel,ssh,jerry
root@pineapple:/home/jerry # groups jerry
jerry wheel jerry ssh
```

### Changing user information (interactive)

`chfn`
or
`chpass`

## Securing

* <https://fleximus.org/howto/secure-freebsd>

## Networking

* <https://www.cyberciti.biz/faq/freebsd-unix-force-dhcp-client-to-get-a-new-lease/>

## Hardware info

<https://www.cyberciti.biz/tips/freebsd-display-information-about-the-system.html>

* `dmidecode` (from dmidecode)
* `sysctl -a hw.model`
* `uname -mrs`
* `pciconf -lv`
* `usbconfig -v`
* `camcontrol devlist`
* `lsusb -v` (from usbutils)

Disk

<https://linuxhint.com/list-disks-freebsd/>

* `geom disk list`
* `sysctl kern.disks`
* `gpart show ada0`

# Jails on ZFS

We run Jails on ZFS subvolumes to easily create, destory and manage the jails

See also https://docs.freebsd.org/en/books/handbook/jails/

```
zfs create zpool/jails
zfs set mountpoint=/data/jails zpool/jails
zfs create zpool/jails/<jailname>
```

Create `/etc/jail.conf` (see `man jail.conf`)

```
# Typical static defaults:
# Use the rc scripts to start and stop jails.  Mount jail's /dev.
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown jail";
exec.clean;
mount.devfs;

# Dynamic wildcard parameter:
# Base the path off the jail name.
path = "/data/jails/$name";

gitea {
	ip4.addr = 192.168.2.200;
}
```

Enable jail service `/etc/rc.conf`
```
jail_enable="YES"
```

Use `bsdinstall` to download a FreeBSD installation. NOTE for installation FTP client (proxy) must be allowed in the firewall. Or a HTTP mirror must be selected...

```
# bsdinstall jail /here/is/the/jail
```

Start all jails or single
```
service jail start
service jail start <jailname>
```

Don't forget to install SSH for easy management to the jail (instead of chrooting into the folder)

```
chroot /here/is/the/jail
pkg install ssh
```

Enable ssh in `/etc/rc.conf` 
```
sshd_enable="YES"
```

```
vi /etc/ssh/sshd_config
# change the PermitRootLogin line to "yes" and remove the comment sign at the start
sysrc sshd_enable="YES"
service sshd start
passwd
# enter root password for your jail's root user
```

Restart jail

```
service jail restart <jailname>
```

Console without SSH

```
service jail console 1
```

# PF firewall enable FTP client using ftpproxy

Install ftp proxy

```
pkg install ftpproxy
```

# bhyve vm manager

* <https://github.com/churchers/vm-bhyve>
* noVNC web client: https://novnc.com/info.html
* https://gyptazy.com/howto-managing-vm-on-freebsd-with-bhyve-and-vm-bhyve/
* https://docs.freebsd.org/en/books/handbook/virtualization/#virtualization-host-bhyve

## Boot environments

* https://wiki.freebsd.org/BootEnvironments
* https://klarasystems.com/articles/managing-boot-environments/

* `beadm`
* https://forums.freebsd.org/threads/updating-freebsd-with-zfs-boot-environments-beadm.84866/

# Virtual networking

vxnet

```
I'll try to create a complete guide soon. But here's step 1 of doing it manually just to get the jails on separate hosts to talk to each other. (using vxlan)

Assuming your external interface is named em0 on both hosts and each is assigned an IP address of 192.168.0.10, and 192.168.0.11 respectively.

First configure Bastille (minus the pf.conf) per Bastille docs

Jail host 1:

route add -net 224/8 -interface em0

ifconfig vxlan create vxlanid 42 vxlanlocal 192.168.0.10 vxlangroup 224.0.2.6 vxlandev em0 inet 10.10.99.2/24

bastille create testjail 13.2-RELEASE 10.10.99``.20 vxlan0

Jail host 2:

route add -net 224/8 -interface em0

ifconfig vxlan create vxlanid 42 vxlanlocal 192.168.0.11 vxlangroup 224.0.2.6 vxlandev em0 inet 10.10.99.3/24

bastille create testjail 13.2-RELEASE 10.10.99``.30 vxlan0
```

https://www.reddit.com/r/freebsd/comments/160uss5/comment/jxq4cax/?utm_source=share&utm_medium=web2x&context=3

## Networking

Show active internet connections: `netstat`
Show open sockets: `sockstat` 

## Installing updates: fix IGNORE_OSVERSION

```
root@pineapple:/home/jerry # pkg update
Updating FreeBSD repository catalogue...
Fetching data.pkg: 100%    7 MiB   7.4MB/s    00:01
Processing entries:   0%
Newer FreeBSD version for package zziplib:
To ignore this error set IGNORE_OSVERSION=yes
- package: 1303001
- running kernel: 1302001
Ignore the mismatch and continue? [y/N]: y
```

```
WARNING: FreeBSD 13.2-RELEASE-p4 HAS PASSED ITS END-OF-LIFE DATE.
Any security issues discovered after Tue Jul  2 02:00:00 CEST 2024
will not have been corrected.
```

* `freebsd-update fetch`
* `freebsd-update install`

Specific release upgrade `freebsd-update upgrade -r 13.3-RELEASE`

## calibre-web

* Install python311 and python311-sqlite and rust
* Create venv with `python -m venv ~/venvs/venv311-calibre-web`
* Activate venv with `. ~/venv/venv311-calibre-web/bin/activate`
* `pip install calibre-web`


Error: native python module not installed need from ports:

```
ImportError: No module named _sqlite3
```

See <https://github.com/janeczku/calibre-web>

## Distro (package) URLs and mirroring

* https://pkg.freebsd.org/
* http://distcache.freebsd.org/
* Mirroring https://docs.freebsd.org/en/articles/hubs/