Sonos & Windows 10 Firewall

enter image description here

Recently I had been having issues with my Sonos controller talking to my Local music library. Both of them installed on the same machine which is in VLAN 1, where as my speakers are on VLAN 2. I was receiving errors such as Error 1002, unable to connect to...., Cant find media etc.

I narrowed the issue down to Windows firewall blocking something even though I had already created "Allow" rules.

Turning off Windows Firewall fixed the issue and my Sonos Speakers could stream my local media library. However I'm not happy turning off a firewall, so started digging deeper.

I checked each individual Firewall which had automatically been created when installing and running the Sonos controller on the PC.

Bingo - I found under the Scope option that the Sonos Library and Sonos Controller firewall rule had an exemption that would only allow connections from devices on a local subnet and blocking anything from a remote IP /Subnet. Allowing all remote IP's or remote subnets fixed the issue but rather than leaving it open like this, I defined my 'remote subnet' of VLAN 2 in the list. This fixed my issue but also kept my firewall rule relevant.

enter image description here

To add further security I changed the "remote IP / Subnet address" from my VLAN 2 subnet to just the IP addresses of my Sonos Speakers on VLAN 2. Now the only devices able to access my Sonos local library are the Sonos Speakers.

Lets Encrypt and Wildcard Certs

Le-logo

Lets Encrypt now supports the use of a wildcard certificate.

What this mean is that rather than having to list all your sub domains in the SSL cert, you can now add *.mydomain.com. It also mean that if you add an additional sub domain you wont have to re-apply for new certificate.

So how does it work?

For this guide I will use LE64.exe - it's a Microsoft Windows command line app which fetches the cert for us. We just need to plug in some commands to get what we need.

This setup presumes you have access to your domain registrar and that you know how to add domain records, in this case a TXT record.

1. Download LE64 from - https://github.com/do-know/Crypt-LE/releases

2. Extract the zip to a working directory i.e. C:\LE64 and you should see a LE64.exe.

3. Create a bat file in the same folder, call it le64.bat

4. In the bat file we need to add the custom attributes or commands. Edit the bold italics below with your details.

le64.exe --key account.key --email "[email protected]" --csr domain.csr --csr-key domain.key --crt domain.crt --export-pfx mypfxpassword --domains "*.***mymedia.cf***" --generate-missing --handle-as dns --api 2 --unlink

This command will create the CSRs, CRT, Key and a PFX cert with a password.

Save the BAT file.

5. Run the le64.bat (its currently in test mode). A command window will open and after a few lines of text it will stop and ask you to add a DNS record with your Domain Registrar to verify you own the domain name.

enter image description here

6. Head over to your domain registrar. For this guide I will be using Cloudflare. Log in and head to DNS or DNS records.

enter image description here

  1. Add the TXT record with the text string from the command line window, should look something like the below when entered.

enter image description here

  1. You now have to wait a few minutes for the Records to propagate the internet. Can be up to 30mins or more in some cases.

To test the propagation, open a CMD prompt and enter the following

nslookup -q=txt _acme-challenge.mymedia.cf

Press enter and if the propagation was successfull it should return the txt value you entered. If it fails to find it, wait a little longer and try again. If the TXT doesnt match, re-enter it again with your Domain Registrar.

9. If the text records matched, hit enter on the le64.bat window to continue with fetching the certificates. You should now have FAKE Lets Encrypt certs. Reason they are fake is that this was it test mode. If all worked ok you now have to repeat from No.4 above but adding --live to the end of the BAT file. Like below-

le64.exe --key account.key --email "[email protected]" --csr domain.csr --csr-key domain.key --crt domain.crt --export-pfx mypfxpassword  --domains "*.mymedia.cf" --generate-missing --handle-as dns --api 2 --unlink --live

You will need to change the DNS TXT record as it will be different this time. Also once the above has completed and you have the certs, you can delete the TXT record with your domain registrar.

N.B.

Previously with DNS verification that the above uses, come renewal time you will have to re-verify your DNS. However I have tested it with le64, aslong as the CSR and CSR.key are kept in the same folder and that you renew your certificate with at least 30 days still left on the cert then you wont have to do the DNS verification again.

Sonos, Unifi, VLAN and Firewalls.

enter image description here

Carrying on from a previous post - Unifi & Sonos VLANs. If you are like me and you have your Sonos Devices segregated on an IoT VLAN and the Sonos Controllers (iPhone etc) on a different VLAN then you will probably need to do some firewalling.

A little Background

VLANs are used for many reasons, segregating networks, preventing multicast packets traversing networks, security amongst other reasons. In this case I wanted all my IoT devices on its own network (VLAN) as there are many security risks with IoT devices and the a separate VLAN for my main LAN. With this I wanted to block all communication from IoT_VLAN to Main_VLAN, however I wanted my Main_VLAN to still be able to communicate with some devices on the IoT_VLAN i.e. Sonos Speakers.

So following on from the previous post where we setup the VLANs and IGMP-Proxying, we will now look at the Unifi Firewalls.

Firewalls work on rules and the rules work in descending order, i.e. if data hits the firewall it will check the rules from the top downwards until it finds a matching rule.

Firewall

In Unifi there are various Rule headings, WAN, LAN and Guest and each has a IN, OUT and LOCAL. For this guide we will be working with LAN IN - the data is coming from the LAN INTO the USG.

Lets create some rules, these will be in order Top to Bottom.

The first rule is created because when the Controller on Main_VLAN creates a connection with the Speaker on IoT_VLAN we want the speaker to be able to talk back to the controller, hence we create a rule to allow established connections but do not allow it to open new connections.

Name - Allow Established
Enabled - On
Rule Applied - Before pre-defined rules
Action - Accept
IPv4 Protocol - All
States - Established and Related
Source - Address group - Any
Destination - Address group - Any

Next Rule is to allow Sonos Speakers to contact Main_VLAN

Name - SONOS_To_Main_VLAN
Enabled - On
Rule Applied - Before predefined rules
Action - Accept
IPv4 Protocol - All
Address Group - Create a group with all the Sonos Speaker IP addresses
Destination - Network - Main_VLAN

Final rule is to block all other data from IoT_VLAN to Main_VLAN

Name - Block IoT_VLAN to Main_VLAN
Enabled - On
Rule Applied - Before predefined rules
Action - Drop
IPv4 protocol - All
Source - Network - IoT_VLAN
Destination - Network - Main_VLAN

And that's it. With these rules devices on IoT_VLAN shouldnt be able to contact devices on Main_VLAN, however Main_VLAN can still contact the Sonos Speakers.

This is what the Rule Page looks like

firewall rule

NGINX Blacklist IPs and Subnets

The ideal way to blacklist is at the router or firewall level. However there is an option to whitelist or blacklist using NGINX.

I use the following site to get a list of dodgy IP's http://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt

Copy and Paste that txt file into Notepad++

We now need to change the formatting for NGINX.

In Notepad ++ press Ctrl + H - this will open the replace menu.

enter image description here

Enter the details above.

  • Find What - ^
  • Make sure to have a space after the 'DENY'.
  • Click 'Replace All'.

And then use the details below,

enter image description here

  • Find What - $
  • Replace with - ;
  • And then 'Replace All'

Save the file as blacklist.conf and save it in the NGINX Conf folder.

Finally add this to the NGINX.conf in the HTTP Block

include blacklist.conf;

Restart NGINX and now all the IPs and Subnets listed will be blocked. Anyone trying to access your server from a blocked IP will get a HTTP 403 error, Access forbidden.

NGINX Log Rotation (MS Windows)

enter image description here

By Default NGINX logs all IPs going through the reverse proxy. The log will keep growing in size.

To ease of maintainance and troubleshooting, it is advisable to get NGINX to create a new access.log everyday.

If NGINX is running on Windows this can be accomplished using a BAT file.

Create a new BAT file with the following

@echo off
SET DATE=%date%
SET DAY=%DATE:~0,2%
SET MONTH=%DATE:~3,2%
SET YEAR=%DATE:~6,4%
SET DATE_FRM=%YEAR%-%MONTH%-%DAY%


ECHO %DATE_FRM%

REM ECHO %YEAR%
REM ECHO %MONTH%
REM ECHO %DAY% 

move C:\nginx\logs\Access.log C:\nginx\logs\Old_Logs\Access_%DATE_FRM%.log
move C:\nginx\logs\Error.log C:\nginx\logs\Old_Logs\Error_%DATE_FRM%.log
call C:\nginx\nginx -p C:\nginx -s reopen

Change the Path to the path of your NGINX Log folder. Also create a new folder in the 'Logs' folder called 'Old_Logs'

Save the BAT file.

We now need to create a Scheduled Task to run this BAT file once a Day.

Create a Basic Task

enter image description here

Daily Task or Weekly depending on how often you want to create a new log.

Choose a Time for it to change logs, i chose 00:00:01 so it would create a new log after midnight.

Next select the location of the BAT file and click next until your seen the screen below.

enter image description here

Make sure to put a tick in the 'Open the properties dialog....' box and click finish.

For The Task to restart NGINX the same user has to run the Task Scheduler and the Service.

Select the correct user in 'Change User or Group' and tick the 'Run with highest privileges' box and click 'ok'.

Next run 'services.msc'

Find your NGINX Service and right click on it 'properties'.

On the 'log on' tab change it from 'Local System Account' to 'This Account' and enter the same username as you did for the Task Scheduler.

Finally click Apply and Ok. And that's it. The task will run, move the access.log to the new folder and rename it with the date. NGINX will then create a new access.log file and repeat.