imthenachoman / How-To-Secure-A-Linux-Server

An evolving how-to guide for securing a Linux server.
Creative Commons Attribution Share Alike 4.0 International
17.38k stars 1.11k forks source link

Guide for LXD #59

Closed elesiuta closed 3 years ago

elesiuta commented 4 years ago

I recently put together some notes for myself for using LXD, if there's interest I can clean them up a bit more and make a pull request.

My reasons for using LXD came down to:

My notes:

Main references

setup

sudo snap install lxd lxd init accept defaults to everything (don't need ip6 though, can disable later with lxc network set lxdbr0 ipv6.address none)

create container

lxc launch ubuntu:20.04 \<container name>

disable autostart

lxc config set \<container name> boot.autostart false

list containers (note container ip, interface is the internal name inside container)

lxc list

run commands in container or enter interactive shell

lxc exec \<container name> -- [command to run in container] lxc exec \<container name> -- sudo --login --user ubuntu lxc exec \<container name> bash

forward traffic

\<server local interface> := probably enp34s0, check with 'ip link show' on host \<server local ip> := self explanatory \<server port> := port you want to forward from host to container \<container ip:port> := get ip from lxc list, port that is listening inside container sudo iptables -t nat -I PREROUTING -i \<server local interface> -p TCP -d \<server local ip> --dport \<server port> -j DNAT --to-destination \<container ip:port> -m comment --comment "forward to container"

list iptables rules

sudo iptables -t nat -L PREROUTING

make rules persist across reboots

sudo apt install iptables-persistent sudo netfilter-persistent save

devices and mounts

https://www.cyberciti.biz/faq/how-to-add-or-mount-directory-in-lxd-linux-container/ https://askubuntu.com/questions/610513/how-do-i-share-a-directory-between-an-lxc-container-and-the-host https://github.com/lxc/lxd#can-i-bind-mount-my-home-directory-in-a-container https://github.com/lxc/lxd/blob/master/doc/userns-idmap.md

check devices

lxc config device show \<container name>

mount (read only by default)

lxc config device add \<container name> \<device name> disk source=\<path on host> path=\<path on container>

mount (add write permission)

use command 'id' to check uid and gid on host and container (all probably 1000) lxc config set \<container name> raw.idmap "both 1000 1000"

remove mount

lxc config device remove \<container name> \<device name>

restart container

lxc restart \<container name>

ways to check containers (and make sure they are unprivileged)

lxc config show --expanded \<container name> | grep privileged ps -ef | grep \<process in container> # make sure not running as root lxc config get \<container name> security.privileged # If that shows "true", then the container is privileged, otherwise it is not lxc list security.privileged=true # check all at once

imthenachoman commented 4 years ago

This is great. I will work to add it in. Might be a few as we just moved and I'm knee deep in unpacking.

elesiuta commented 4 years ago

Sounds good, a couple things I noticed/forgot to mention.

The mounts being read only or read/write depends on their owner and permissions which I usually set to 755 (so they're not actually read only by default if you use 777). To actually make them read only, regardless of permissions, use lxc config device add <container name> <device name> disk source=<path on host> path=<path on container> readonly=true edit: this is better than what I wrote before about using a read-only bind mount on the host

The other thing is ufw doesn't start after a reboot if using netfilter-persistent (at least on ubuntu). The fix found here is to add the line After=netfilter-persistent.service after Before=network.target in the file /lib/systemd/system/ufw.service

elesiuta commented 4 years ago

Another thing I found that might be of interest is that a compromised container could potentially do MAC or IP spoofing on the bridge (source)

To prevent this, you can enable MAC and IP filtering by running this command for every container (if you already ran your containers, it'll probably be assigned a new IP address, which you can also set yourself by setting ipv4.address on the eth0 device)
lxc config device override <container name> eth0 security.mac_filtering=true security.ipv4_filtering=true

imthenachoman commented 3 years ago

Have you thought about creating a new guide just for LXD? I worry if we merge the two it might create confusion for folks who aren't using LXD? Thoughts?

elesiuta commented 3 years ago

Have you thought about creating a new guide just for LXD? I worry if we merge the two it might create confusion for folks who aren't using LXD? Thoughts?

I was starting to work on one but stopped due to no longer using LXD myself and migrating my setup to use just docker.

I also agree, combining LXD with this guide might create confusion for people who probably don't need LXD and just be too much. It's probably still worth mentioning along with AppArmor for people who wish to go that route and that's it. I think you took a good approach by sticking to the base OS and this is a great guide as it is.

imthenachoman commented 3 years ago

Thank you!

elesiuta commented 3 years ago

I think we can close this issue now, I was going to add a couple links mentioning this to the AppArmor section, but since it hasn't been written yet and I'm not familiar enough to write anything on it, I'll just leave it up to whoever does to decide if they want to mention this.