Contents

Setting up Home Assistant in a virtual environment on Intel NUC (or any other x86 machine)

Setting up Home Assistant in a virtual environment on Intel NUC (with mqtt, ssh, samba, docker…) based on Ubuntu Server 17.10 / Intel NUC7i3BNH

Originally for Taymurf (Taymurf#0781 on DiscordHA) Big thanks to him for beta testing and motivating me to do this!

V 0.1 (Jan 2018) Tested on HomeAssistant Release 0.62.1

V 0.2 (Jun 2018) Migrated to Ubuntu 18.04 LTS with dist upgrade

V 0.3 (Apr 2020) Migrated to Ubuntu 20.04.3 LTS with dist upgrade

The basic steps in this How-To reflect till today my current working setup. I’ve made minor changes to some services (e.g. migrated the Mosquitto Server to Docker). Ubuntu switched from SysV to systemd. If you did aswell, please notice that all commands starting with /etc/init.d/SERVICE are now (re)started/stopped via systemctl (re)start/stop SERVICE.

Main reason for writing this “How-to” is to give a helping hand to those willing to switch their working appliance to something more powerful. I recently moved from a Raspberry Pi 3 to an Intel NUC and these were the initial steps I took…

I changed some (imho) basic settings in the system to ensure a basic level of minimum security. I am not a Linux Guru nor a nationwide “Security Consultant” so any constructive criticism or advice on how I can improve this guide is greatly appreciated.

I mainly use “vim” for editing files. Feel free to use any other editor of your choice (i.e. nano).

The following wildcards (placeholders) will be used throughout the text:

EDITOR - Replace with whatever editing program you prefer to use.

USER - Replace with your main user account

HAUSER - Replace with your Home Assistant user account

Greetings to the whole community (especially the devs!) and thanks for making this stunning project so vital and awesome.

0.) Preamble


If anything isn’t working as it should, contact me on any of my mentioned channels. I try to respond as soon as possible!

If you need general help visit https://home-assistant.io/help/

PLEASE KEEP IN MIND:

THIS IS NOT AN OFFICIAL DOCUMENT MAINTAINED BY HOME ASSISTANT!

This is a written account of what has worked for me and tested by another user of

Home Assistant making the switch from a Raspberry Pi 3 to an Intel NUC.

1.) Before Install


Update to the latest BIOS Version and adjusting it Download the appropriate Version for your System from https://downloadcenter.intel.com/.

Detailed instructions how to update are found here: https://www.intel.com/content/www/us/en/support/articles/000005636/mini-pcs.html

Initial upgrade failed for me with any USB Stick larger 64GB. Basically, format any USB Stick with exFAT (respectively FAT32) and copy the *.bio file onto it.

Insert the Stick into a USB Port of your choice and shutdown the PC. Reboot into the BIOS Updater by pressing “F7” while starting up the NUC. Select the stick and file you copied earlier and wait for it to complete.

Reboot to the BIOS (Press F2) Changes I made to the BIOS include selecting the “Quiet” model for the fans and disabled any lighting for HDD activity. I prefer a quiet and stealthy device on my shelf.

2.) Installation


Download the Ubuntu Server (https://www.ubuntu.com/download/server)

Use Etcher or rufus (Etcher: https://etcher.io/ / rufus: http://rufus.akeo.ie/) on Windows to flash the image to an USB Stick of your choice.

Any Stick should work.

On Linux: Stick to: https://help.ubuntu.com/community/Installation/FromUSBStick On MacOS: Etcher is also available.

In general any *NIX based system with dd should work.

Connect a Keyboard, a monitor and an ethernet cable to your PC. Initial networking setup is done via DHCP, most routers will assign an IPv4/IPv6. If not, assign a static ip and gateway manually (If DHCP fails, the installer will tell you).

Insert the Stick and reboot, the Ubuntu Installer should come up (if not, enter the Boot Menu from the BIOS and select your stick). Select your prefered Language/Region and choose a username/password of your choice. Later we will set a strong password to this user. Main configuration and maintenance of the system is done by that user via sudo.

By default, Ubuntu does not allow any direct logins with the “root” user (which makes sense imho). I decided NOT to setup an encrypted home container.

Please keep in mind that all information stored on the harddrive could easily be read by anyone with physical access to the system (I.e. if it gets stolen). Maybe I will add the Setup of LUKS/LVM in a future version or update this how-to if there is some public demand.

Check the determined Timezone and correct the Settings if necessary.

In my setup I select Guided - use entire disk and set up LVM for the server. LVM makes it easy to add some hard drive space in the future if needed. LVM means Logical Volume Manager and is more powerful than playing around with parted and mkfs.X Read more about LVM and why it is good here: https://wiki.ubuntu.com/Lvm

Wait for “apt” to finish. I’ve decided to let the system maintain it’s security updates automatically.

If you are the natural born sysadmin feel free to keep updating in your hand. Install OpenSSH Server and Samba in the next dialogue simply by marking it with an asterisk. SSH will handle our remote connection and Samba is used for editing the HASS config in a Windows share.

Install GRUB to the MBR if you don’t want to setup a multi-OS system (what i guess you don’t want to).

Remove the Stick, hit Continue and watch your server come to life! Login in with the user and password created earlier.

3.) Initial System Config


After logging in for the first time, use sudo -s and enter your password to become the root user.

Remember this command, you will need it many times… First we will do some updates. Use apt-get update && apt-get full-upgrade -y to update all packages installed at this point.

sudo:

As seen before working as the root user is vital.

Later, we will change the password for the user to something more complex and secure. The Login to System with your default user will later be strengthened with an openssh key login. I decided to give this user the permission to use “sudo” without typing the password all the time.

PLEASE KEEP IN MIND: Everybody with your password (or ssh key) is able to modify, read or delete anything on that system!

type cd /etc/sudoers.d && EDITOR 010_USER-nopasswd to change the directory and create an empty config file (replace USER with your own user).

BE VERY CAREFUL ON THIS STEP: if you enter anything wrong in this file and save it (giving you a syntax error) you will most likely have to reinstall your server. It only takes about 10 minutes to do over, but it’s a hassle.

It is possible to regain access with any “Linux Live Media” but that would go beyond the scope of the document.

Enter USER ALL=(ALL) NOPASSWD: ALL and save the file and after that sudo -k for applying the changes. Next time any use of the sudo command won’t prompt you for a password. If you want to, logout with logout (or Ctrl + D ) an re-login. The command sudo whoami should output “root” without any password requested.

Sample output:

1
2
3
4
root@hostname:~# cd /etc/sudoers.d
root@hostname:/etc/sudoers.d# nano 010_USER-nopasswd
root@hostname:/etc/sudoers.d# cat 010_USER-nopasswd
USER ALL=(ALL) NOPASSWD: ALL

Setting up a static IP for the system:

I don’t want to rely on any DHCP Daemon for assigning a IP to my HASS server. If for whatever reason your DHCP server fails or the static route in your router is lost you won’t be able to connect to it. Type ip link show to find out the device name of your ethernet card.

1
2
3
root@hostname:~# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 . .

In my case the network device is named “eno1”. Yours may differ. My server will listen to the Address “192.168.0.10” and use the Google DNS Servers (8.8.8.8,8.8.4.4).

IMPORTANT! Change those to whatever you want but KEEP IN MIND this address has be unique and should not appear in your DHCP daemons ip pool. Usually every DHCP Daemon reservers a pool for assigning IP Addresses. In my case I configured the DHCP service with a static address 192.168.0.10 for HomeAssistant and a pool range from 192.168.0.200 to 192.168.0.254.

If unsure about your net settings use ifconfig to display the actual settings of your network card and ip route |grep default for the gateway address Sample for my network:

1
2
3
4
> root@hostname:~# ifconfig eno1
eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.10 netmask 255.255.255.0 broadcast 192.168.0.255 ether ff:ff:ff:ff:ff:ff txqueuelen 1000 (Ethernet) RX packets 31680033 bytes 40287320994 (40.2 GB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 17808340 bytes 2638877725 (2.6 GB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@hostname:~# ip route |grep default
default via 192.168.0.1 dev eno1 proto static

In previous Ubuntu Version static interfaces were configured in “/etc/network/interfaces”. This changed in Ubuntu 17.10. Use “cd /etc/netplan” to change to config directory as root (sudo -s if you are not already root).

*NOTE: .yaml files are very sensitive to indenting properly so make sure you follow the spacing of the file and don’t just copy and paste what I have here.

For an example of what it should look like with proper indents,use wget -O 01-netcfg.yaml https://chris.0x711.de/01-netcfg.yaml to store a local copy of my config.

Use EDITOR 01-netcfg.yaml to alter the configuration. Change to the following (altered to match your config) and save:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    eno1:
      dhcp4: no
      dhcp6: no
      addresses: [192.168.0.10/24]
      gateway4: 192.168.0.1
      nameservers:
        addresses: [8.8.8.8,8.8.4.4

use netplan apply to execute the changes.

Check if everything works: type ip addr|grep inet the output should be something like:

1
2
root@hostname:~# ip addr|grep inet
inet 127.0.0.1/8 scope host lo inet 192.168.0.10/24 brd 192.168.0.255 scope global eno1

use ping -c 5 home-assistant.io to test the internet connectivity:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
root@hostname:~# ping -c 5 home-assistant.io
PING home-assistant.io (104.31.87.190) 56(84) bytes of data.
64 bytes from 104.31.87.190 (104.31.87.190): icmp_seq=1 ttl=57 time=11.1 ms
64 bytes from 104.31.87.190 (104.31.87.190): icmp_seq=2 ttl=57 time=10.3 ms
64 bytes from 104.31.87.190 (104.31.87.190): icmp_seq=3 ttl=57 time=10.5 ms
64 bytes from 104.31.87.190 (104.31.87.190): icmp_seq=4 ttl=57 time=11.6 ms
64 bytes from 104.31.87.190 (104.31.87.190): icmp_seq=5 ttl=57 time=10.6 ms

--- home-assistant.io ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms rtt min/avg/max/mdev = 10.320/10.872/11.683/0.501 ms

The ping command send 5 packets to the Home Assistant homepage. You could use any domain for this test (google.com, nasa.gov, xkcd.com….)

More information about netplan is found here: https://wiki.ubuntu.com/Netplan

Time for the first reboot of your machine using sudo reboot (Apply the kernel updates and see if the static ip setup works).

After rebooting you could remotely connect to your server. For doing that in my case (replace the IP with the one you’ve set up above):

Linux/MacOS: ssh -l USER 192.168.0.10

Windows: Use PuTTY and enter in hostname your address.

Congratulations!

You’ve just set up a Ubuntu server with a static IP-Address on your NUC!

4.) Setting up sshd and login with key


Login to your box and become the root user with sudo -s.

Use apt-get install -y pwgen pwgen is a handy tool for generating passwords.

Use pwgen 40 to generate some random passwords with the length of 40 characters. Default settings use a-z, 0-9 and some capitalized characters. If you want to you could mix in some special characters. See man pwgen.

For those of you how want to learn more about security and complexity of passwords start with this (very popular) comic: https://xkcd.com/936/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
root@ubuntu:~# pwgen 40
mohFiwie1ilix7aox8maiThid4xeb7goj1eedail
uvohchoo4exa4YaeBei0Deiy9ieh4shaigicheec
Ailiu7Thaisai7ahvei9Eez5ru4IeruChaiceibu
ooShii8eeWieg0saiweeghaeph2cheerae9ieBai
johc4cai7du8ahP5ae1peeSh7eeZu1WaiLohtahP
aiz0shaeshiezeihu1Uneexee5vohcaipaow2nah
Faet5phiesiuQuohzo5dienge5OhMu7gool7ahJa
aighoo0ui2echoovooci4suoti6AeYie3ie1epai
toobiangai8Einguac2phue5Aej0ii1shaeRaaph
feoBoongashii5chaesh4chaedieDohc7ooyeej4
IdoeHa3Ailaeca7luK8etheegee3ooraiF9geeme
Yee3bucei0eghizohthei5aJoquahX7iejeediev
teesohmiiRaeshietheemai9Uungae8no8uguveu
iw7xeiC8phuomahngee5iech9rielodoh1te1ohL
chahKohsai2jie5oohaereiviP6ne8Aixuez2shi
yah2ZooBookoo8egherohJah8otoofahziek4Ohw
...

Time to change the installer password (I had chosen password (ultra secure)) to something more complex.

Choose one from your list (NOT MINE!) and type passwd USER.

After submitting that command, copy and paste a password of your choice and hit Enter.

Ensure you did it right with a new ssh/Putty session and login with your new password.

WARNING: Note down the password in a safe place! You won’t be able to login to your server with the old one anymore!  

For Windows I use Keepass (https://keepass.info/).

A Beginner’s guide can be found here.

Continue as USER (if you are still root enter exit or press Ctrl + D). Use mkdir .ssh && cd .ssh to create a hidden directory and change to it. Create a ssh key with ssh-keygen -t rsa -b 4096 -C USER2nuc and save it to USER2nuc (or any other distinct name of your choice). You could leave the passphrase password empty. Again it is your personal choice and it would without a doubt be more secure to add one. My server is only in my local network and I store all of my keys on an encrypted drive, so I left it blank for convenience of logging in. If you ever going to expose the machine (or to be more precise the ssh port) to the open internet do yourself a favor and increase the security with this simple two factor mechanism. (OT: you could use the autotype function in keepass to launch a putty profile and autotype the password)

Next we add the keyfile to a file called authorized_keys.

To do so: cat USER2nuc.pub >> authorized_keys

Note: The command won’t generate any output

1
2
USER@ubuntu:~/.ssh$ cat USER2nuc.pub >> authorized_keys
USER@ubuntu:~/.ssh$

Use cat USER2nuc to display the private key and copy & paste it to some secure space.

If you want to connect from a linux shell to the nuc (assumed you saved the key to /path/to/USER2nuc-keyfile and the remote ip is ..0.10) use this command: chmod 600 /path/to/keyfile (makes the file only readable by the owner) and after that ssh -l USER -i path/to/USER2nuc-keyfile

On Windows download and open putty keygen

Use FileLoad private key and select the private key you saved before. Click on Save private key and choose again a safe location. Putty keygen will create a .ppk file which is needed.

Next step will be editing the openssh daemon config file: Use sudo -s to become root, change the directory and edit the config with cd /etc/ssh && EDITOR sshd_config

Changes I made (remove the leading # to activate the options):

1
2
3
4
5
6
7
8
9
Port 2222
. . .
# Authentication:
#LoginGraceTime 2m
PermitRootLogin no
StrictModes yes
MaxAuthTries 2
. . .
DenyUsers homeassistant

Add the DenyUsers line at the bottom of the document. Save the file and exit the EDITOR.

I changed the port to something not typically sshd-associated. Many bots try to bruteforce into poorly administered remote machines.

Changing the port is filed under Security by Obscurity. Login for the user root is denied in general.

Even if someone exploits your machine and changes the root password the intruder can’t login using ssh. We deny the user homeassistant access to the system.

In a later section we will add this user to run HASS. One more discussable option for the config would be PasswordAuthentication no.

If you decide to do so please remember:

If you lose your openssh/.ppk keyfile you are locked out of the system!

Use /etc/init.d/ssh restart to load the new settings. Open Putty. Enter the IP Address and your new port.

Enter a session name like HA-nuc in the lower half of Putty window. Click on the left side on Data under Connection and fill in USER under Auto-login username.

Click on Auth under Connection SSH and supply the path to your private keyfile.ppk created earlier. Go back to Session and hit Save on the lower right side.

A double-click onto the profile name will now connect and auto login you to your server!

5.) Setting up the HomeAssistant User and creating a Samba share


Become root with sudo -s and type adduser HAUSER Enter a password of your choice. I used homeassistant for both HAUSER and the password because remote login to the machine via ssh is denied.

More secure in a general way would be setting up a strong password (see 4.)).

All fields for name etc. are not needed. Just hit enter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
root@hostname:~# adduser HAUSER
Adding user `HAUSER ...
Adding new group `HAUSER (1001) ...
Adding new user `HAUSER (1001) with group `HAUSER ...
Creating home directory `/home/HAUSER ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for homeassistant
Enter the new value, or press ENTER for the default
 Full Name []:
 Room Number []:
 Work Phone []:
 Home Phone []:
 Other []:

 Is the information correct? [Y/n]

To add the HAUSER to more system groups use adduser HAUSER GROUPNAME

In my case i want to use a Z-Wave stick and the HAUSER needs to be a member of the group dialout.

If any special Home Assistant component will need a special group it is normally documented in the official docs.

I assume samba was installed in the initial setup process if not run apt-get install samba -y as root.

WARNING: I’ve decided to create a public share. Everybody in your home network could read and modify the files inside the share!

If you don’t want a public share stick to this: Ubuntu | Creating Samba from the console

It might be also a good idea to to disable the autostart of samba and start it only up if you need to modify the configuration of HomeAssistant:

To do so enter systemctl disable smbd as root. systemctl start smbd is used via ssh to start the service and systemctl stop smbd to stop it.

Change the Samba config directory and edit the config file with cd /etc/samba && EDITOR smb.conf I added the following at the end of the file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

[homeassistant]
path = /home/HAUSER/.homeassistant
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = HAUSER

[winshare_USER]
path = /home/USER/winshare
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = USER

Create the folders with mkdir /home/USER/winshare and mkdir -p /home/HAUSER/.homeassistant

We need to set the correct file permissions to both folders:

Execute that with chown -R USER:USER /home/USER and chown -R HAUSER:HAUSER /home/HAUSER

Restart samba with service smbd restart.

Test your shares from Windows: Press Windowsbutton + R and enter 192.168.X.Y (the static ip of your server).

Two folders should appear and you should be able to create or delete files.

6.) Installing the Virtual Environment and (finally) HomeAssistant


Detailed information is found at: https://home-assistant.io/docs/installation/virtualenv/

Start with sudo apt-get install python3-pip python3-venv -y

Do all of the following commands as the HAUSER.

Use sudo su -s /bin/bash HAUSER to work as HAUSER Change directory with cd /home and run python3 -m venv HAUSER cd HAUSER && source bin/activate actives the virtual environment.

Run python3 -m pip install wheel followed by python3 -m pip install homeassistant

For a first test run hass --open-ui HASS is preparing the first start and you should see a lot of installing in the log. Give it some time.

Check http://your-ip:8123 and hopefully there it is! =)

You should find inside the HA Windows samba share some newly generated files (e.g. the configuration.yaml)

Hit Ctrl + C once inside the terminal window to stop the process and continue with setting up autostart via systemd. Enter exit to return to your normal user and type sudo -s to become root.

Change to cd /etc/systemd/system and run EDITOR home-assistant@HAUSER.service *NOTE: File will be blank. Copy over the following and save the file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[Unit]
Description=Home Assistant
After=network-online.target

[Service]
Type=simple
User=%i
ExecStart=/home/homeassistant/homeassistant_venv/bin/hass -c "/home/homeassistant/.homeassistant"

[Install]
WantedBy=multi-user.target

Reboot your Machine and wait for HA to come up under http://:8123

Congratulations! You’ve just setup your own Ubuntu Server with HASS!

7.) Updating and managment of the service


dale3h made a great command line tool for controlling and managing HomeAssistant

See https://github.com/dale3h/hassctl for more information.

Install it with: sudo curl -o /usr/local/bin/hassctl https://raw.githubusercontent.com/dale3h/hassctl/master/hassctl && sudo chmod +x /usr/local/bin/hassctl

Run hassctl log once to auto-generate the config files. The program will terminate with an error but we fix that in the next step. Use sudo EDITOR /etc/hassctl.conf and change the paths:

VIRTUAL_ENV= to /home/HAUSER HASS_CONFIG=/home/HAUSER/.homeassistant HASS_USER=HAUSER

Example Output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
root@hostname:~$ cat /etc/hassctl.conf
# /etc/hassctl.conf: `hassctl' configuration.
#
# A full description of the configuration file is at
# https://github.com/dale3h/hassctl

HASSCTL_BRANCH=master

VIRTUAL_ENV=/home/homeassistant/homeassistant_venv_3.8
PIP_EXEC=$VIRTUAL_ENV/bin/pip3
HASS_EXEC=$VIRTUAL_ENV/bin/hass

HASS_CONFIG=/home/homeassistant/.homeassistant
HASS_USER=homeassistant
HASS_SERVICE="home*assistant*"

OZW_LOG=$HASS_CONFIG/OZW_Log.txt

Now test it with hassctl restart && hassctl log.

You should see Home Assistant rebooting. To stop the process use Ctrl + C.

As a backup (if hassctl stops working for whatever reason) you could manually start, stop or update HomeAssistant with those commands:

Stop: sudo systemctl stop home-assistant@HAUSER.service

Start: sudo systemctl start home-assistant@HAUSER.service

Logfile: sudo journalctl -fu home-assistant@HAUSER.service

Update: First stop the service (see above) then become the HAUSER: sudo su -s /bin/bash HAUSER:

Change to the homedir and activate the VENV: cd /home/HAUSER/ && source bin/activate

Upgrade HASS with: python3 -m pip install --upgrade homeassistant Use exit to leave the virtual environment and use the start command.

8.) Other useful services and helpful hints


Services I would personally advise are mosquitto as a mqtt broker and docker-io.

Mosquitto

Mqtt offers a widespread and reliable way for communicating with plenty of devices.

See the official component page for further information: https://home-assistant.io/components/mqtt/

Become root with sudo -s. Use apt-get install mosquitto mosquitto-clients -y to install the server and useful tools. Stop the service with service mosquitto stop Change to the configuration directory with cd /etc/mosquitto

The configuration file (mosquitto.conf) is mainly self explaining. If you are lazy grab a copy of my config with wget -O mosquitto.conf https://chris.0x711.de/mosquitto.conf

Use mosquitto_passwd -c /etc/mosquitto/pwfile MQTTUSERNAME to create a user called MQTTUSERNAME with a corresponding password.

Restart the service with service mosquitto restart

Subscribe to your server with mosquitto_sub -h <your-ip> -p 1883 -t '#' -u MQTTUSERNAME -P MQTT_PASSWORD -v -R

Send a test message from another shell (or Putty session) with: mosquitto_pub -h <mosquitto-server-ip> -p 1883 -u MQTTUSERNAME -P MQTT_PASSWORD -t test/hello -m world

The output of the stream should display

1
2
root@hostname:~# mosquitto_sub -h 192.168.0.10 -p 1883 -t '#' -u test -P test -v -R
test/hello world

Your server is ready to use! For adding another user use mosquitto_passwd /etc/mosquitto/pwfile ANOTHERUSERNAME and restart the service.

*Note: You could use the same user on multiple devices but please keep in mind that the client-id has to be different.

Docker

I mainly use docker to generate some neat looking statistics for my sensor data. To install docker use the command apt-get install docker.io -y as root.

Phil Hawthorne made some great articles on how to and why using docker in combination with Home Assistant is a great idea.

See his blog for more information: https://philhawthorne.com/getting-started-with-grafana-influxdb-for-home-assistant/

Thank you for reading and if this document has helped you in any way let me know it if it was worth the effort and time ;)