====== Pi-Hole - Setup Pi-Hole running in LXC ======
[[Pi-Hole:Setup Pi-Hole running in LXC:Not Working|Not Working]]
===== Create an LXC Container =====
lxc init ubuntu:20.04 pihole
returns:
Creating pihole
----
===== Check the status =====
lxc info pihole
returns:
Name: pihole
Location: none
Remote: unix://
Architecture: x86_64
Created: 2021/01/03 20:40 UTC
Status: Stopped
Type: container
Profiles: default
----
===== Start the Container =====
lxc start pihole
----
===== Check the status again =====
lxc info pihole
returns:
Name: pihole
Location: none
Remote: unix://
Architecture: x86_64
Created: 2021/01/03 20:40 UTC
Status: Running
Type: container
Profiles: default
Pid: 844849
Ips:
eth0: inet 10.207.221.25 vethd19000f6
eth0: inet6 fd42:4242:fe05:c96b:216:3eff:fecd:bd67 vethd19000f6
eth0: inet6 fe80::216:3eff:fecd:bd67 vethd19000f6
lo: inet 127.0.0.1
lo: inet6 ::1
Resources:
Processes: 76
CPU usage:
CPU usage (in seconds): 10
Memory usage:
Memory (current): 419.70MB
Memory (peak): 462.38MB
Network usage:
eth0:
Bytes received: 779.53kB
Bytes sent: 20.10kB
Packets received: 195
Packets sent: 201
lo:
Bytes received: 1.68kB
Bytes sent: 1.68kB
Packets received: 19
Packets sent: 19
**NOTE:** This shows the container is running.
It also shows it has an IP address of 10.207.221.25, which is probably not what is wanted as this is different from the host subnet range.
----
===== Assign the bride profile to the container =====
**IMPORTANT:** Do NOT use the macvlan profile as it does not allow the host to access the Container.
Every other device can access the Container, just not the host, unless the host is placed into Promiscuous mode.
See: [[LXC:Make your LXD containers get IP addresses from your LAN using macvlan|Make your LXD containers get IP addresses from your LAN using macvlan]]
See: [[LXC:Profiles:Profiles:Create a Bridge Profile|Create a Bridge Profile]]
lxc profile assign pihole default,bridgeprofile
returns:
Profiles default,bridgeprofile applied to pihole
**NOTE:** The assign command must have both the default and bridgeprofile profiles as shown.
----
===== Check the status once again =====
lxc info pihole
returns:
Name: pihole
Location: none
Remote: unix://
Architecture: x86_64
Created: 2021/01/03 20:40 UTC
Status: Running
Type: container
Profiles: default, bridgedprofile
Pid: 844849
Ips:
eth0: inet 192.168.1.150 br0
eth0: inet6 fe80::216:3eff:fe38:3c04 br0
lo: inet 127.0.0.1
lo: inet6 ::1
Resources:
Processes: 79
CPU usage:
CPU usage (in seconds): 10
Memory usage:
Memory (current): 427.35MB
Memory (peak): 462.38MB
Network usage:
eth0:
Bytes received: 1.29kB
Bytes sent: 1.47kB
Packets received: 11
Packets sent: 11
lo:
Bytes received: 1.68kB
Bytes sent: 1.68kB
Packets received: 19
Packets sent: 19
**NOTE:** The IP address has changed to 192.168.1.150.
This is the correct subnet matching that of the host.
If the result does not show an IP for eth0, then just wait a few seconds and retry. It seems to take a while sometimes before the container picks up the change. Do not panic if this continues to not show. Just continue with the steps.
----
===== Set the default login password =====
lxc exec pihole -- passwd ubuntu
New password:
Retype new password:
passwd: password updated successfully
**NOTE:** There is a default user account named **ubuntu**, which is being used here.
You could setup a completely different user account if wanted.
**NOTE:** An alternative way to do this is by:
lxc exec pihole -- /bin/bash
Then to issue the following command, and enter a secure password:
passwd ubuntu
----
===== Set up a proxy to allow web traffic into the LXD container (Optional) =====
On the host, not the container, add a proxy:
lxc config device add pihole web proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
returns:
Device web added to pihole
**NOTE:** Ensure that the Container is stopped before running this.
If this fails, then not a worry and may not be needed. You may get an error such as
Error: Failed to start device "web": Error occurred when starting proxy device: Error: Failed to listen on 0.0.0.0:80: listen tcp 0.0.0.0:80: bind: address already in use
----
===== Get a Shell inside the Container =====
lxc exec pihole bash
**NOTE:** Alternatively try:
lxc console pihole
returns:
To detach from the console, press: +a q
**NOTE:** Press .
pihole login: ubuntu
Password:
**NOTE:** Enter **ubuntu** for the login and use the password you set for that account.
This should then log you into a standard ubuntu system:
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-58-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sun Jan 3 20:57:34 UTC 2021
System load: 2.2 Temperature: 37.0 C
Usage of /home: unknown Processes: 24
Memory usage: 0% Users logged in: 0
Swap usage: 0% IPv4 address for eth0: 192.168.1.148
1 update can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
To run a command as administrator (user "root"), use "sudo ".
See "man sudo_root" for details.
----
===== Check the Network =====
Ensure that LXC is configured properly; i.e. that it is able to access the internet.
ip a
returns:
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
20: eth0@if4: mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:38:3c:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.150/24 brd 192.168.1.255 scope global dynamic eth0
valid_lft 6056sec preferred_lft 6056sec
inet6 fe80::216:3eff:fe38:3c04/64 scope link
valid_lft forever preferred_lft forever
**NOTE:** The eth0 interface does show it has an IP address which is part of the host subnet, i.e. 192.168.1.150.
Try to ping.
ping 192.168.1.1 -c 1
returns:
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.410 ms
--- 192.168.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.410/0.410/0.410/0.000 ms
**NOTE:** Change the ping address as needed to the correct subnet.
If the ping fails, then try to restart networking on the container:
netplan apply
----
===== Configure an IP on the Container =====
Pi-Hole needs a static IP, so set one.
By default the Container uses DHCP, so each time it starts it would receive a different IP.
# This file is generated from information provided by the datasource. Changes
# to it will not persist across an instance reboot. To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
#network:
# version: 2
# ethernets:
# eth0:
# dhcp4: true
#
# Let NetworkManager manage all devices on this system
network:
version: 2
#renderer: NetworkManager
renderer: networkd
ethernets:
eth0:
dhcp4: no
# disable existing configuration for ethernet
addresses: [192.168.1.150/24]
gateway4: 192.168.1.1
nameservers:
addresses: [192.168.1.1]
dhcp6: no
**NOTE:** This sets a static IP address, which is needed for Pi-Hole.
The default dhcp has been commented out, but can be deleted from this file.
The actual netplan filename may be slightly different; Edit the actual filename within the **/etc/netplan** directory.
----
===== Apply the network changes =====
netplan apply
----
===== Exit the Shell =====
exit
----
===== Restart the Pi-Hole Container =====
lxc restart pihole
----
===== Try to ping the Pi-Hole Container from the Host =====
ping 192.168.1.150
returns:
PING 192.168.1.150 (192.168.1.150) 56(84) bytes of data.
64 bytes from 192.168.1.150: icmp_seq=1 ttl=64 time=0.031 ms
64 bytes from 192.168.1.150: icmp_seq=2 ttl=64 time=0.027 ms
64 bytes from 192.168.1.150: icmp_seq=3 ttl=64 time=0.026 ms
64 bytes from 192.168.1.150: icmp_seq=4 ttl=64 time=0.044 ms
64 bytes from 192.168.1.150: icmp_seq=5 ttl=64 time=0.028 ms
--- 192.168.1.150 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4101ms
rtt min/avg/max/mdev = 0.026/0.031/0.044/0.006 ms
**NOTE:** If this step fails, bash back into the container lxc exec pihole bash
and then restart the network: netplan apply
Then exit and retry the ping and if that works you should be able to access Pi-Hole from the web.
----
===== Get a Shell inside the Container =====
lxc exec pihole bash
----
===== Update the Container =====
sudo apt update
sudo apt upgrade
----
===== Install additional packages =====
sudo apt install cron curl wget openssh-server vim ca-certificates
**NOTE:** Some of these additional packages may already be installed. Not a concern.
The **ca-certificates** package is needed to prevent errors later with curl.
Without this, errors such as: **curl: (60) SSL certificate problem: unable to get local issuer certificate** may be seen.
Of course, this package, as well as any other package can be installed later with commands such as:
apt install ca-certificates
----
===== Install Pi-Hole =====
sudo curl -sSL https://install.pi-hole.net | bash
or
curl -sSL https://install.pi-hole.net -o pihole.sh
**NOTE:** The 2nd option here just downloads the script. It does not actually install Pi-Hole until it is run.
This is a little safer, as it allows you to check the code in the script against trojans etc. Once you are sure it is okay then run:
sudo bash pihole.sh
Select the defaults until the DNS screen and then choose Cloudflare as your DNS.
* Accept all the rest of the defaults and be careful not to change them. This will assure that you get the admin web interface and that statistics are logged.
* The installation will continue for a few minutes after you answer the prompts.
* After your installation completes, you will receive a message telling you to set up the DHCP settings on your router to make the address of your Pi-Hole the primary DNS for your network.
* That will insert the Pi-Hole as the “man-in-the-middle” to scrutinize all DNS names before they are either passed to the Internet or “Pi-Holed”.
----
**NOTE:** If an error occurs, then either fix the firewall rules or try:
curl -sSL https://install.pi-hole.net | PIHOLE_SKIP_OS_CHECK=true sudo -E bash
----
===== Set the Pi-hole password =====
When you return to the prompt in the terminal session, enter the following command to set your Pi-hole password:
pihole -a -p
----
===== Try to access Pi-Hole from a Web Browser =====
192.168.1.150
**IMPORTANT:** Make sure that the URL you type is does NOT contain **https://** in front of the IP Address.
**NOTE:** If this fails, then try to access it from a different device than the host.
If this works, then mostly good. Primary reason host cannot access is that the network needs to run in Promiscuous mode.
Configure Promiscuous mode then retry.
An alternative option is to use a **Bridged Profile**.
----
===== Exit the Pi-Hole Container =====
exit
----
===== Get Information on the Pi-Hole Container =====
lxc info pihole
returns:
Name: pihole
Location: none
Remote: unix://
Architecture: x86_64
Created: 2021/01/07 14:59 UTC
Status: Running
Type: container
Profiles: default, bridgeprofile
Pid: 708446
Ips:
eth0: inet 192.168.1.150 vethb3f914e9
eth0: inet6 fe80::216:3eff:fecb:fcf8 vethb3f914e9
lo: inet 127.0.0.1
lo: inet6 ::1
Resources:
Processes: 88
CPU usage:
CPU usage (in seconds): 20
Memory usage:
Memory (current): 266.82MB
Memory (peak): 276.11MB
Network usage:
eth0:
Bytes received: 2.45MB
Bytes sent: 3.70MB
Packets received: 18537
Packets sent: 3905
lo:
Bytes received: 4.05MB
Bytes sent: 4.05MB
Packets received: 60882
Packets sent: 60882
----
**TIP:** If this still does not work, then perhaps delete the Pi-Hole Container and restart.
lxc delete pihole
lxc profile delete macvlan
lxc profile delete bridgeprofile
No need to delete the profiles if you are happy with these. Just delete the actual Container and follow the steps above.
----
===== Have the LXC Container Start Automatically =====
By default, LXC containers may not start automatically.
lxc config set pihole boot.autostart true
Ensure that LXC is set to start containers at boot.
# LXC_AUTO - whether or not to start containers at boot
LXC_AUTO="true"
**NOTE:** Also check file /etc/default/lxc-net, just in case this overrides this setting.
**NOTE:** Autostart is mainly used to select which containers to start.
When the host system boots, LXC decides the order and the delay between each startup.
----
===== Show the Pi-Hole Container Configuration File =====
lxc config show pihole
returns:
architecture: x86_64
config:
boot.autostart: "true"
image.architecture: amd64
image.description: ubuntu 20.04 LTS amd64 (release) (20210105)
image.label: release
image.os: ubuntu
image.release: focal
image.serial: "20210105"
image.type: squashfs
image.version: "20.04"
volatile.base_image: 21da67063730fc446ca7fe090a7cf90ad9397ff4001f69907d7db690a30897c3
volatile.eth0.host_name: veth9b7de9bd
volatile.eth0.hwaddr: 00:16:3e:4c:1b:d7
volatile.idmap.base: "0"
volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
volatile.last_state.power: RUNNING
volatile.uuid: 10e59167-cf89-4919-bb1c-9e701d15e08c
devices: {}
ephemeral: false
profiles:
- default
- bridgeprofile
stateful: false
description: ""
**NOTE:** This file will not be created until a change is made to it.
In this case, the autostart config done previously has enabled this.