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!
cvoid#4858 on Discord HA Server
V 0.1 (Jan 2018) tested on HomeAssistant Release 0.62.1
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.
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.
Download the Ubuntu Server (https://www.ubuntu.com/download/server)
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
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.
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!
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 rnstall 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.
USER ALL=(ALL) NOPASSWD: ALL
and save the file and after that
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.
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.
ip link show
to find out the device name of your ethernet card.
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 (126.96.36.199,188.8.131.52).
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:
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).
.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.
to alter the configuration.
Change to the following (altered to match your config) and save:
# 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.27/24] gateway4: 192.168.0.1 nameservers: addresses: [184.108.40.206,220.127.116.11]
to execute the changes.Check if everything works:
ip addr|grep inet
the output should be something like:
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
ping -c 5 home-assistant.io
to test the internet connectivity:
root@metis:~# ping -c 5 home-assistant.io
PING home-assistant.io (18.104.22.168) 56(84) bytes of data.
64 bytes from 22.214.171.124 (126.96.36.199): icmp_seq=1 ttl=57 time=11.1 ms
64 bytes from 188.8.131.52 (184.108.40.206): icmp_seq=2 ttl=57 time=10.3 ms
64 bytes from 220.127.116.11 (18.104.22.168): icmp_seq=3 ttl=57 time=10.5 ms
64 bytes from 22.214.171.124 (126.96.36.199): icmp_seq=4 ttl=57 time=11.6 ms
64 bytes from 188.8.131.52 (184.108.40.206): 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 (https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) 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 KEY LOGIN
Login to your box and become the “root user” with “sudo -s”.
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:
root@ubuntu:~# pwgen 40
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: http://www.petersmittenaar.com/keepass-why-and-how-to-use-it-effectively.php
Continue as USER (if you are still root enter “exit” or press Ctrl + D).
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
USER@ubuntu:~/.ssh$ cat USER2nuc.pub >> authorized_keys
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 <your-server-ip>
On Windows download and open “putty keygen” from https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
Use “File” → “Load 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):
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.
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 :
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
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:
path = /home/HAUSER/.homeassistant
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = HAUSER
path = /home/USER/winshare
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = USER
Create the folders with
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
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/
sudo apt-get install python3-pip python3-venv -y
Do all of the following commands as the HAUSER.
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.
python3 -m pip install wheel
python3 -m pip install homeassistant
For a first test run
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:
[Unit] Description=Home Assistant After=network-online.target [Service] Type=simple User=%i ExecStart=/home/HAUSER/bin/hass -c "/home/HAUSER/.homeassistant" [Install] WantedBy=multi-user.target
Run “systemctl –system daemon-reload” to reload the systemd configs and “systemctl enable home-assistant@HAUSER”
root@hostname:/etc/systemd/system# systemctl –system daemon-reload
root@hostname:/etc/systemd/system# systemctl enable home-assistant@HAUSER
Created symlink /etc/systemd/system/multi-user.target.wants/home-assistant@HAUSER.service → /etc/systemd/system/home-assistant@HAUSER.service.
Reboot your Machine and wait for HA to come up under “http://<your-ip>:8123”
Congratulations! You’ve just setup your own Ubuntu Server with HASS!
7.) UPDATING AND MANAGEMENT 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”
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”
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.
Mqtt offers a widespread and reliable way for communicating with plenty of devices.
See the official component page for further information:
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
root@hostname:~# mosquitto_sub -h 192.168.0.10 -p 1883 -t ‘#’ -u test -P test -v -R
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.
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:
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 😉