Creating an OpenVPN client for bridging traffic between two networks.

This is going to be somewhat backwards, I will follow this up with a creating an OpenVPN server post at a later time.


Be aware that this client will be setup in AWS so there will be AWS references in the article. This can be easily translated to your own network.

A prerequisite for this is a OpenVPN server at a remote location that is not in AWS, your office for example.
Spin up an ami, preferably CentOS you can use the Amazon Linux AMI as well as it is built from the same meat and potatoes.
I used an ami with the ID of ami-033e6106180a626d0 this is a CentOS linux ami.
Make sure your instance has an elastic IP and it can be reached externally via SSH.
Always work with sudo, I use the sudo -i command to accomplish this.

*Note the service on the OpenVPN client is called openvpn-client@aws.service

 

Configure your OpenVPN server for the Client

You will need to do two things, assign the client a static IP when it connects to the VPN,
and advertise the subnets that sit behind the VPN client.
SSH into your Server instance.
Work as sudo, create a CCD directory, and a client file.

sudo -i
mkdir /etc/openvpn/ccd
cd /etc/openvpn/ccd
touch myuser

Edit the myuser file and add the following.

ifconfig-push 10.8.1.254 255.255.255.0
iroute 172.31.1.0 255.255.255.0
push "route 172.31.1.0 255.255.255.0 10.8.1.254"
push "redirect-gateway def1"
route 172.31.1.0 255.255.255.0 10.8.1.254

*Note that the file name myuser in this directory should reflect the user id that the AWS client will connect with and it should be unique.

This OpenVPN server configuration uses only one set of certificate files, but I created a unique LDAP user ID called myuser

that only this server connects with. This is defined by the server configuration line username-as-common-name each time an LDAP user connects

instead of the certificate name it will be identified as the LDAP user ID.

As such anytime myuser connects it is assigned a static IP of 10.8.1.254 as defined by the ifcongif-push line as defined in the myuser file.

The iroute 172.31.1.0 255.255.255.0 advertises the AWS subnet that sits behind the AWS client. 

You also don’t need the last 3 lines, especially push “redirect-gateway def1” only add that if you want to redirect all gateway traffic from AWS via the VPN. The other 2 are redundant as those routes are pushed and advertised via iroute and the entries below so either or. Navigate to the open vpn directory /etc/openvpn and edit the server.conf file and add the following.

push "route 172.31.1.0 255.255.255.0"
client-config-dir ccd
route 172.31.1.0 255.255.255.0
route 10.8.1.254 255.255.255.0

The above advertises the new route to all the clients that connect and tells the clients the configuration directory is ccd.

ipp.txt does not work for pushing static IPs as such we use the ccd directory here.

route 172.31…in this file in conjunction with the iroute 172 in the myuser file direct all traffic to said client.

route 10.8…in this file in conjunction with ifconfig-push 10.8 in the myuser file assign a static IP to the myuser client.

 

Install and configure OpenVPN on the client.

Use your key and remote into the client Linux instance. Work with sudo

sudo -i

Update your instance

yum update -y 

Install enterprise linux repository (EPEL)

yum install epel-release -y

Update your repository again

yum update -y

Install open vpn and wget

yum install -y openvpn

Create a client directory in the OpenVPN directory and move into it.

mkdir /etc/openvpn/client
cd /etc/openvpn/client

Create two configuration files.

touch aws.conf
touch login.conf

Edit the login.conf with your user id and password. First line is the user id and the second line is your OPEN VPN password.

nano login.conf

The file should look like this.

myuser
MyP@sswerd$

Save and exit the file.

Edit the aws.conf file using nano.

The file should look something like this.

client
dev tun
cipher AES-256-CBC
tls-client
tls-auth ta.key 1
remote-cert-tls server
auth-user-pass /etc/openvpn/client/login.conf
keepalive 10 60
proto udp
remote vpn.mydomain.com 1194 udp
topology subnet
pull
persist-tun
persist-key
user nobody
group nobody
verb 3
<ca>
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
</cert>
<key>

-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----

</key>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
-----END OpenVPN Static key V1-----
</tls-auth>

Obviously add your own certificates to the aws.configuration file. Save the file and exit.

I include my certificates in the configuration file.

You don’t have to, you can move them somewhere else and reference them in the configuration file.

Also note that aws.conf will be the name of the service, you can name the file whatever you would like but then you have to reflect this in the configuration of the service.

 

IP Forwarding on the Client

Next you need to configure IP forwarding on the client as you do on the Server. Without this the bridging will not work.

First check and make sure your firewall is disabled on the AMI, generally they are by default.

systemctl status firewalld

If it’s disabled, move on, otherwise do the follwing.

systemctl stop firewalld
systemctl disable firewalld

Next enable IP forwarding.

nano /etc/sysctl.conf

Add the following line to the conf file.

net.ipv4.ip_forward = 1

Restart the network service.

systemctl restart network

Test your open vpn connection. If it is working disconnect and move on to the next step.

openvpn --config aws.conf

 

Create an OpenVPN service on the Client.

Next you will create an open VPN service which will restart and reconnect if it crashes.

Last thing you want is the tunnel crashing and not coming back up.

Create the service.

systemctl ebnable openvpn-client@aws.service

Note that the client portion between the openvpn and @ symobol is the client directory we created earlier, and the aws after the @ is the aws.conf file we created.

This will create the service.

Next start the service and check the status.

systemctl start openvpn-client@aws.service
systemctl status openvpn-client@aws.service

The status should spit out the following.

● openvpn-client@aws.service - OpenVPN tunnel for aws
Loaded: loaded (/usr/lib/systemd/system/openvpn-client@.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2019-06-06 17:03:54 UTC; 1h 7min ago
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
Main PID: 4209 (openvpn)
Status: "Initialization Sequence Completed"
CGroup: /system.slice/system-openvpn\x2dclient.slice/openvpn-client@aws.service
└─4209 /usr/sbin/openvpn --suppress-timestamps --nobind --config aws.conf

Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: TLS: soft reset sec=0 bytes=82353/-1 pkts=1140/0
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: VERIFY OK: depth=1, C=CA, ST=AB, L=Edmonton, O=Some Company, OU=IT, CN=domain.com, name=server, emailAddress=admin@domain.com
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: VERIFY KU OK
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: Validating certificate extended key usage
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: VERIFY EKU OK
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: VERIFY OK: depth=0, C=CA, ST=AB, L=Edmonton, O=Some Company, OU=IT, CN=domain.com, name=server, emailAddress=admin@domain.com
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Jun 06 18:03:54 ip-172-31-1-81.ca-central-1.compute.internal openvpn[4209]: Control Channel: TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384, 4096 bit RSA

Now we need to make sure that this service starts automatically when the server reboots or the tunnel crashes.

Check to see if the service is enabled to auto start.

systemctl is-enabled openvpn-client@aws.service

If you get the following that means the service will auto start.

[root@ip-172-31-1-81 /]# systemctl is-enabled openvpn-client@aws.service

enabled

Otherwise do the following.

Open the openvpn service.

nano /etc/systemd/system/multi-user.target.wants/openvpn-client\@aws.service

Under the [Service] heading add the line Restart=always

[Unit]

....

[Service]

...

Restart=always

[Install]

...

Test the service to see if it restarts by either rebooting the AMI or do the following.

Check the PID of the process, kill it, and see if it restarts.

systemctl status openvpn-client@aws.service

Should see something along the lines of….

Main PID: 4209 (openvpn)

Kill the process to see if it restarts

kill -9 4209

If you do a status again the process should have a new PID.

 

That’s it, now don’t forget to add your routes to the Networking side of things. Your gateway on the Server side needs to know how to get to the AWS client and it’s networks.

If you are putting this in AWS, rememeber to add the routes in the Route table and make changes to the security group as well. Traffic needs to flow both ways.

 

AWS Route Table Changes

In AWS find the VPN that the AWS client lives in and locate the route table for said Subnet.

In this case its called OpenVPN_RT

Click on this route table. 

Then Edit the route.

 

Click Add route… then type in the CIDR block of the Network in your remote location, the network that sits behind the VPN server.Select instance and select the AWS Client VPN instance that you have created.

This will translate the route to the instances Network Interface once you click save routes.

Do the same for the VPN CIDR and any other CIDRs that live behind the VPN Server.

 

Your security group should look like this.

Note the SSH entries, they were added in order to initially setup the linux boxes.

If your traffic is routing properly you can remove these last two entries as these are no longer needed and you can reach the AMIs via the AWS subnet IP.

Ignore the MKT VPC entry this is used for a peering connection.

PROFIT!

 

Resources:

https://www.digitalocean.com/community/tutorials/how-to-set-up-and-configure-an-openvpn-server-on-centos-7

https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-1-practical-examples

Vivaldi mobile Beta is here.

1560035641

On Sept 9th 2019 Vivaldi finally delivered their Mobile experience in beta form.

First impressions are good, it’s fast and the UI is fairly intuitive. The menus aren’t buried 10 layers deep, so intuitive in fact it took me all of 30 seconds at first boot to sync my data with Vivaldi servers. I hope they keep it this way. If their desktop experience is anything to follow they probably will.

I have been using their desktop browser for a while now, it’s a good alternative to Chrome and Firefox. Their desktop browsing experience is built on chromium, so all Chrome plugins work in Vivaldi as well.

For those curious about Vivaldi’s hostory, the President of this company used to run the show at Opera before it was sold to the Chinese.

He took the money from that sale and started his own browser company, which is now Vivaldi. Me, I can finally ditch the Opera Mobile experience and start using Vivaldi mobile.

Still in beta mind you so I’m sure it will have some hiccups. I also have yet to figure out how to sync my passwords and bookmark data.

While I was writing this post, the mobile browser ended up syncing all my data. Have to be patient I guess.

Windows 10 (1803 1903) UEFI Autounattend.xml network installation.

The original post is here, use it to setup a PE image to capture the WIM.

Also be aware that as of version 1809 of the AIK, Microsoft has separated the PE installation environment from the AIK kit.

You will need to download it separately here. It’s on the same page as the AIK download, look for the link there.

If you get any installation errors you can bring up command prompt via Shift + F10, run notepad.exe and locate the installation logs in the c:\%windir%\panther folder.

1903

For version 1903 use AIK version 1809, you will not be able to edit the autounattend with AIK 1903 and AIK 1809 is able to edit and use 1903 images.

Also for version 1903 make sure you populate the windows PE – Microsoft Windows Setup neutral – UserData – ProductKey – Key  … some previous versions of Windows did not require this.

In Windows 10 version 1803 a new installation prompt has been added. As such in pass 7 oobeSystem, you need to add input locale Component which is located in amd64_Microsoft-Windows-International-Core_neutral.

One other thing that I have changed in the newer version of the Autounattend.xml is that the installer now formats the drive to boot as UEFI and the install.wim (Windows image) is located on my network. Custom wim files over 4GB will not fit on a FAT32 formatted flash drive, so your option is to format it as NTFS or put the image on the network. For complexity we will use the network method. As such because you are now grabbing the installation image of the network you may need to inject network drivers into the boot.wim image in the sources folder on the flash drive/installation media. This will allow the installation media to connect to the network and grab the windows installation image from a shared folder. Note that there are two images in the boot.wim file, index 1 and index 2, you want to inject the network drivers into the index 2 in the image file which is the Microsoft Windows Setup image.

C:\>dism /Get-ImageInfo /ImageFile:c:\temp\bootwim\boot.wim

Deployment Image Servicing and Management tool
Version: 10.0.17134.1

Details for image : c:\temp\bootwim\boot.wim

Index : 1
Name : Microsoft Windows PE (x64)
Description : Microsoft Windows PE (x64)
Size : 1,394,055,012 bytes

Index : 2
Name : Microsoft Windows Setup (x64)
Description : Microsoft Windows Setup (x64)
Size : 1,553,327,748 bytes

The operation completed successfully.

DISM GUI no longer seems to support the latest version of Windows 10 either, so all DISM commands need to be performed from the Deployment and Imaging Tools Environment.

Mount the boot.wim and perform the following commands to add the network driver(s) to your image. Note in the above example that the image is 64 bit so only 64 drivers are required for your hardware.

C:\>dism /Mount-Image /ImageFile:c:\temp\bootwim\boot.wim /Index:2 
/MountDir:c:\temp\mount

Deployment Image Servicing and Management tool
Version: 10.0.17134.1

Mounting image
[==========================100.0%==========================]
The operation completed successfully.

C:\>dism /Image:c:\temp\mount /Add-Driver:c:\temp\drivers\64 /Recurse

Deployment Image Servicing and Management tool
Version: 10.0.17134.1

Image Version: 10.0.14393.350

Searching for driver packages to install...
Found 1 driver package(s) to install.
Installing 1 of 1 - oem1.inf: The driver package was successfully 
installed.
The operation completed successfully.

C:\>dism /Unmount-Image /MountDir:c:\temp\mount /Commit

Deployment Image Servicing and Management tool
Version: 10.0.17134.1

Saving image
[==========================100.0%==========================]
Unmounting image
[==========================100.0%==========================]
The operation completed successfully.

As you can see they are 3 simple commands and with the Recurse switch you can add multiple network drivers to the image if you have varying pieces of hardware deployed on your network.

Below is an example of an UEFI Autounattend.xml used to install windows from the network.

  • In pass 1, windowsPE, the Autounattend.xml, formats 2 drives in the machine, a primary one and a secondary one.
  • Also in pass 1 the image is then installed from a network location using domain credentials. You need to make sure the account has read permissions to the network location. The image is installed to disk “0” partition “4”.
  • In the specialize pass, pass 4, the machine is added to the domain using the “joinadmin” account using the Microsoft-Windows-UnattendedJoin component.
  • Finally in version 1803 of windows maybe even 1709 a new installation component was added that asks for Network and Locale information, you can fill this in using the Microsoft-Windows-International-Core component in pass 7

My suggestion would be to copy and paste the below text into a blank text file and save it as an .xml extension. Then take that and open it in Windows System Image manager.

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
                <UILanguage>en-US</UILanguage>
            </SetupUILanguage>
            <UserLocale>en-CA</UserLocale>
            <UILanguageFallback>en-CA</UILanguageFallback>
            <SystemLocale>en-US</SystemLocale>
            <InputLocale>en-US</InputLocale>
            <UILanguage>en-US</UILanguage>
        </component>
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <Disk wcm:action="add">
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Type>Primary</Type>
                            <Size>250</Size>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>2</Order>
                            <Type>EFI</Type>
                            <Size>100</Size>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>3</Order>
                            <Size>128</Size>
                            <Type>MSR</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>4</Order>
                            <Extend>true</Extend>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                    <ModifyPartitions>
                        <ModifyPartition wcm:action="add">
                            <Order>1</Order>
                            <PartitionID>1</PartitionID>
                            <Format>NTFS</Format>
                            <Label>Recovery</Label>
                            <TypeID>de94bba4-06d1-4d40-a16a-bfd50179d6ac</TypeID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Order>2</Order>
                            <PartitionID>2</PartitionID>
                            <Label>System</Label>
                            <Format>FAT32</Format>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Order>3</Order>
                            <PartitionID>4</PartitionID>
                            <Label>SOCO</Label>
                            <Format>NTFS</Format>
                            <Letter>C</Letter>
                        </ModifyPartition>
                    </ModifyPartitions>
                    <DiskID>0</DiskID>
                    <WillWipeDisk>true</WillWipeDisk>
                </Disk>
                <WillShowUI>OnError</WillShowUI>
                <Disk wcm:action="add">
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Extend>true</Extend>
                            <Order>1</Order>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                    <ModifyPartitions>
                        <ModifyPartition wcm:action="add">
                            <Label>Storage</Label>
                            <Format>NTFS</Format>
                            <Order>1</Order>
                            <Letter>D</Letter>
                            <PartitionID>1</PartitionID>
                        </ModifyPartition>
                    </ModifyPartitions>
                    <DiskID>1</DiskID>
                    <WillWipeDisk>true</WillWipeDisk>
                </Disk>
            </DiskConfiguration>
            <UserData>
                <ProductKey>
                    <WillShowUI>Never</WillShowUI>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
                <Organization>Some Company</Organization>
                <FullName>Some Company Inc.</FullName>
            </UserData>
            <EnableFirewall>false</EnableFirewall>
            <EnableNetwork>true</EnableNetwork>
            <ImageInstall>
                <OSImage>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>4</PartitionID>
                    </InstallTo>
                    <InstallFrom>
                        <Path>\\server\IT\WIM\Win10-image.wim</Path>
                        <Credentials>
                            <Domain>domain.local</Domain>
                            <Password>MyP@ssw0rd!</Password>
                            <Username>netadmin</Username>
                        </Credentials>
                        <MetaData wcm:action="add">
                            <Key>/IMAGE/NAME</Key>
                            <Value>Windows 10 Pro</Value>
                        </MetaData>
                    </InstallFrom>
                    <WillShowUI>OnError</WillShowUI>
                </OSImage>
            </ImageInstall>
        </component>
    </settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <BluetoothTaskbarIconEnabled>true</BluetoothTaskbarIconEnabled>
            <ComputerName>DTPC-0032</ComputerName>
            <TimeZone>Mountain Standard Time</TimeZone>
            <ShowPowerButtonOnStartScreen>true</ShowPowerButtonOnStartScreen>
            <RegisteredOrganization>Some Company</RegisteredOrganization>
            <ProductKey>VK7JG-NPHTM-C97JM-9MPGT-3V66T</ProductKey>
            <DisableAutoDaylightTimeSet>false</DisableAutoDaylightTimeSet>
            <DoNotCleanTaskBar>true</DoNotCleanTaskBar>
            <RegisteredOwner></RegisteredOwner>
            <OEMName></OEMName>
        </component>
        <component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Identification>
                <Credentials>
                    <Domain>domain.local</Domain>
                    <Username>joinadmin</Username>
                    <Password>MyP@ssw0rd!</Password>
                </Credentials>
                <JoinDomain>domain.local</JoinDomain>
                <MachineObjectOU>OU=DesktopOU,OU=ComputersOU,DC=domain,DC=local</MachineObjectOU>
            </Identification>
        </component>
    </settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <OOBE>
                <VMModeOptimizations>
                    <SkipWinREInitialization>true</SkipWinREInitialization>
                    <SkipNotifyUILanguageChange>true</SkipNotifyUILanguageChange>
                    <SkipAdministratorProfileRemoval>true</SkipAdministratorProfileRemoval>
                </VMModeOptimizations>
                <HideEULAPage>true</HideEULAPage>
                <HideLocalAccountScreen>true</HideLocalAccountScreen>
                <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
                <ProtectYourPC>2</ProtectYourPC>
                <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
                <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
            </OOBE>
            <UserAccounts>
                <LocalAccounts>
                    <LocalAccount wcm:action="add">
                        <Password>
                            <Value>BAAcwADAAcgBCEAUAAcwG8Ak=</Value>
                            <PlainText>false</PlainText>
                        </Password>
                        <Description>Local User Account</Description>
                        <DisplayName>LocalUser</DisplayName>
                        <Group>Administrators</Group>
                        <Name>User</Name>
                    </LocalAccount>
                </LocalAccounts>
            </UserAccounts>
            <TimeZone>Mountain Standard Time</TimeZone>
            <RegisteredOrganization>Some Company</RegisteredOrganization>
            <RegisteredOwner>IT Department</RegisteredOwner>
        </component>
        <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <InputLocale>en-US</InputLocale>
            <SystemLocale>en-CA</SystemLocale>
            <UILanguage>en-US</UILanguage>
            <UILanguageFallback>en-CA</UILanguageFallback>
            <UserLocale>en-CA</UserLocale>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim:d:/iso/install_w10_1803.wim#Windows 10 Pro" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>

CredSSP, Windows RDP connection error.

Recently Microsoft changed the security in regards to Remote Desktop connections. This was to address a vulnerability that existed with RDP that allowed an attacker to take complete remote control of a Windows PC.

With this came some security changes and you will need to add a registry entry to your machines if you get Security Connection errors in Windows OS and Server OS when you try and use RDP to connect to an older remote machines. When I say older I mean Windows 7 and Server 2008, Windows 8.x might be affected as well.

For more information on CredSSP see this Microsoft article: https://support.microsoft.com/en-ca/help/4056564/security-update-for-vulnerabilities-in-windows-server-2008

In Windows 7 the error looks like the following…

win7

In Windows 10 the error is a little more detailed and looks like this…

To get past this issue all you need to do is add the following registry entry to your machine.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters]
“AllowEncryptionOracle”=dword:00000002

Alternatively here is a reg file in a zip file that you can just run. Make sure you reboot after adding the registry entry.

https://drive.google.com/file/d/13vDjZQqwEGZYNL5wnbig5iOzOs26EKn-/view?usp=sharing

I created a group policy on my Domain to push this registry entry to all computers.

WMI Filtering in Group Policy

Item level targeting is great and all, it works well for granular targeting. But with Item Level Targeting you are limited to only Active Directory components.

WMI or Windows Management Instrumentation consists of a set of extensions to the Windows Driver Model that provides an operating system interface through which instrumented components provide information and notification.

What if I told you you could set up policies that that allow you to target specific users, specific user names, specific hardware, and specific software. Even specific hardware types. You could deploy hardware specific drivers on your domain using WMI flitering.

It’s actually pretty slick, and far superior to anything that SNMP can offer. It is a very powerful tool set for a Sys Aadmin. The level of control for WMI filtering is absolutely amazing and robust. But is it secure? Well that depends, it can be, if you follow best practices there is no reason it shouldn’t be.

WMI filters are similar to SQL queries, for example…

select Version, ProductType from Win32_OperatingSystem where
 ((Version like "10%") and (ProductType = 1))

The above version 10 followed by the wildcard character will select Windows 10 and Server 2016 operating system versions. ProductType = 1 means the desktop OS version, where as type of 3 would mean the server OS version. Finally ProductType = 2 means that the machine is a Domain Controller.

select Version, ProductType from Win32_OperatingSystem where
 ((Version like "6.1%") and (ProductType = 1))

The above is for Windows 7.

select Version, ProductType from Win32_OperatingSystem where
 ((Version like "6.3%") and (ProductType = 3))

Finally the last one is Server 2012 R2.

Note that the name space that this is available in, is root\CIMv2.

If you want to find and query WMI you can use the official tool available from Microsoft, it’s called The WMI Code Creator tool and it’s available here. If the link is dead just search for it. An alternative to this is the NirSoft SimpleWMIView available here, and Wmi Explorer available here.

WMI Code Creator looks something like the following. It allows you to browse all the WMI possibilities and search for property values of WMI classes. For obvious reasons you will need the .NET framework installed on your machine.

 

Creating a WMI Filter is simple. Open up your Group Policy Management application, expand your domain and at the bottom you should have a folder named WMI Filters. In this folder you can also see a collection of WMI Filters and which policies they are applied to.

Right click this folder and select New…

Give your Filter a name and Description, then click Add.

Finish by clicking OK and Save. You have now created a WMI Filter for Server 2016 all versions.

Now you need to apply the filter to a policy. Locate a policy in your Manager, and in the right pane on the bottom under WMI Filtering now you can select the filter you just created.

That’s pretty much it, you can play around with the WMI Code Creator and see that you can do some very granular filtering with this. You can create filters based on OS, CPU, Disk drives anything that you can think of. This is a very powerful tool and if you’re familiar with SQL queries you should have no trouble coming up with some complex filters.

Specific Host Name:

root\CIMV2 – Win32_ComputerSystem – DNSHostName = ‘YourHostname’

 

As a side note if you are a C# .NET developer you can also benefit from WMI using the System.Management namespaces in Visual Studio. You will need to add a reference to it in your Visual Studio project. This allows you to query Microsoft Operating System hardware and retrieve statistics from said machine.

Sample C# Code:

 ManagementObjectSearcher processor = 
 new ManagementObjectSearcher("root\\CIMV2", 
 "SELECT * FROM Win32_PerfFormattedData_Counters_ProcessorInformation");
 foreach(ManagementObject query in processor.Get())
 {
 coreValues.Add((string)query["PercentProcessorTime"]);
 }

Home Media – Part 4 – OSMC/KODI/XBMC

This is part 4 of a series of write ups called Home Media.

Part 1 – The NAS build

Part 2 – The Setup

Part 3 – The Rip

Now that you have a whole infrastructure setup for streaming in your house, what do you do?

First thing is first, you will need some sort of hardware. Be it an old laptop, a Odroid-C2 box, an Android Box or a Raspberry Pi3. Then you will be creating two xml files called Sources.xml and/or AdvancedSettings.xml. These two files are responsible for media sources and database connections respectively. With Advancedsettings in the mix you can also add an SQL instance to your setup.

The benefit to the SQL database is that if you have multiple devices in your home, you can pause your content in one room and resume it in another. Your library info is stored in one place, the databse, and can be easily backed up and restored using software such as HeidiSQL. Library updates can be performed using headless installations of KODI and are picked up by all other devices on the network connected to the DB.

Easiest way to run a headless installation of KODI is to use the LinuxServer.io docker container which they have created and is available from here https://github.com/linuxserver/docker-kodi-headless. This works well if you have a server at home. If you are running a Pi or Odroid device with KODI on it this might not be necessary, since these are always on low power devices. Potentially you can send all update requests to these boxes.

For Laptop and Android Boxes go to their respective app stores and install KODI. On Linux you have to install KODI manually. Head over to Kodi.TV and they have all the packages you need over there. For further installation instructions head over to the KODI wiki.

In this example I will be working with v17.x or K, code named Krypton. For the Odroid-C2 and RaspberryPi I suggest heading over to LibreELEC and grabbing the installation source from there. The equivalent LibreELEC version of KODI version 17 is 8.x. For the Odroid and RPi you will need to image the storage device, SD card or eMMC storage. On Windows use the Rufus software. Alternatively LibreELEC has built their own installation tool to install the OS on a storage device. For further installation instruction for LE suing their tool go to their wiki site. An alternative to LibreELEC is OpenELEC, this has builds for devices that Libre does not support.

Note that when you boot in to KODI for the first time, specifically LibreELEC, you should enable SAMBA and SSH. SAMBA will be useful for copying the xml files to your KODI box later on.

Installation:

Once you have installed Rufus and plugged your SD/eMMC card to your computer start Rufus and locate the drive letter that is the storage device of your choosing.

In Rufus click the drop down list and select DD Image, then to the right of it click the image icon.

Rufus will prompt for a file with a Open selection window. Select the appropriate image and click Open.

It will warn you about erasing all the data on the storage device, accept the prompt and let Rufus run through it’s thing.

Once complete close Rufus and check that your file structure of the SD card look something like the above. The storage device is now ready to be plugged into your hardware and you can proceed to boot it.

Database:

Install the database of your choice. I use MariaDB, it’s a free open source SQL software. It was forked after MySQL was bought out by Oracle. I run this in a docker on my home server. However you like to proceed pick the installation of your choice.

The docker container is available on the Docker hub and can be found here: https://hub.docker.com/_/mariadb/

To run the docker with persistent storage run the following docker commands.

First you need to pull the installation.

docker pull mariadb:latest

An alternative to the latest tag you can use the versions available on the site, 5, 10… etc. Then you will need to run the docker using the docker run command. It will look something like the follwing.

docker run -d –restart=always –net=bridge –name mariadb -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=SomePassword -e MYSQL_USER=kodi -e MYSQL_PASSWORD=kodi -p 3306:3306 mariadb:latest

For Unraid 6 you can use a Docker MariaDB template available here:

https://github.com/Exist2Resist/docker-templates/tree/master/exist2resist

There are 3 key commands you need to execute on the database after you have installed it. You can find the database installation instructions for various OS versions on the KODI wiki.

Make sure after you setup a sa or root user on the database you write down the password. After this log into the database and run the following 3 commands.

  1. Type in: CREATE USER 'kodi' IDENTIFIED BY 'kodi'; and press return
  2. Type in: GRANT ALL ON *.* TO 'kodi'; and press return
  3. Type in: flush privileges; and press return

These commands create a user with the name kodi and password kodi. This will be used in your KODI installations via the advancedsettings.xml file to connect to the database.

sources.xml:

The sources file is used to connect KODI to your network shares and sources for your media and music. A sources file has the <sources></sources> tags at the beginning and end of the file and should look something like the following…

smb: stands for samba, your other option would be nfs which is the file sharing protocol in linux. Also if you notice the above shares are accessible to anyone on the local network. If you want to password protect these shares go ahead but you will need to change the <path>, using the example above to smb://username:password@Tower/Music/.

The sections (<music>), name (<name>) and path(<path>) are all mandatory in the example above. Every other field is optional.

Note that if you are using a database to store the media information you do not need the sources.xml file on all your instances of Kodi. You will only need both files on the instance which updates the library and database. All other instances only need to connect to the database. The database contains a files table which has an idPath column that stores the path to the files.

For further detail on the sources xml you can head over to the KODI wiki, http://kodi.wiki/view/Sources.xml

Note that with the database in the mix you should enable the option to wait for network before starting KODI. This is only available in OpenELEC and LibreELEC builds of KODI. I have not been able to find this in the vanilla KODI, but that should not matter as more than likely these installations will usually run on a box that requires manual KODI start anyways.

advancedsettings.xml:

The advanced settings file has the <advancedsettings></advancedsettings> tags at the beginning and end of the file and below is an example of what the advancedsettings.xml should look like. This file is very fickle and it has a lot of options it can take. Use the example below as a starting point.

<videodatabase> and <musicdatabase> point to an sql instance via the IP address username and password. Default port for sql is always 3306.

Also if you want to pause and resume your playback at different locations in your home, include the <importwatchedstate> and <importresumepoint> tags and set them to true under the <videolibrary> tag. Under the same tag <backgroundupdate> updates the library without any popups of notifications. <recentlyaddeditems> sets the amount of new items that will be visible under the TV Shows and Movies sections. Default I believe is 25, you can set this to whatever.

In version 17+ of KODI the cache tag is pretty important. If you are experiencing the odd buffering interruption while watching content from your file server set this option and have all content buffer.

In previous versions of KODI this option was set under the network tag. Sections 2.8.4 and 2.8.3 of the Advancedsettings.xml wiki, respectively.

Cache buffers the file in memory instead of the local storage. If you notice a lot of stutter on your streams, especially with version 17 if you add this sections the performance should greatly improve. Mind you if you have terrible internet and you are using external or http video sources there are no guarantees. If want to do this you will need to do some math first, use this bit calculator if you’d like, don’t trust google they mess the calculation and conversion up badly. But more on that later.

The cache section looks something like the following.

<cache>
<buffermode>1</buffermode>
<memorysize>477184000</memorysize>
<readfactor>10</readfactor>
</cache>

Buffer mode with value of 1 will cache any content streamed in KODI. Local or remote it doesn’t matter.

Memory size is where you will need to do some converting and calculating. So the max memory size depends on your system and this value can not exceed a third of your max free memory. So if your device is running while playing content with 300 MB of free memory your max memory size should be 100MB or 104857600 bytes. If you don’t adhere to the 1:3 ratio rule, there is a high probability that your box will crash.

Read factor is the speed at which the content gets buffered at or read into memory at. If a files average bit rate is 6MB/s, with a read factor of 10 the file will be read at 60MB/s into the cache buffer. Average bit rate multiplied by the read factor. Take your network bandwidth into consideration when calculating this. If not specified the default is 4.

For further details on the advancedsettings xml you can head over to the KODI wiki http://kodi.wiki/view/Advancedsettings.xml

File placement:

If you enabled SAMBA and SSH on your KODI device you can navigate to the Userdata share of the device and place both xml files there. Even though you don’t need both it is recommended that you do. The network name or IP will be required for you to navigate to the shared folder. You should have enabled SAMBA when you set up your KODI box. During said setup you gave the installation a name, if you kept it default navigating to \\LIBREELEC via file explorer should bring up the box’s shares.

Open up the Userdata folder and you should see some folders and 4 xml files.

Place both the XML files in here.

Alternatively you can SSH into your box using putty or similar software. Default user name is root and the password is libreelec.

Once in there you can use either vi or nano to create both the files and paste the contents. The location of where the file should be stored are as follows.

/storage/.kodi/userdata/

You can create the files manually by performing the following commands in SSH.

nano advancedsettings.xml

Then paste the contents of the file into the window and click ctrl + x, this will prompt you if you want to save the file, type in y and hit enter to confirm the file name.

Repeat the same for the sources file.

A very important step, you will need to set KODI to wait for the network when it boots if you are using a db connection. If you do not do this your library will not populate.

In your add-ons select the LibreELEC Configuration add on.

Then set the Wait for network… option and set it to 10 second. There has not been an instance where 10 seconds has not been enough for me.

Your KODI box should now be ready to go, reboot and enjoy.

Veeam VM Backup software restore agent timeout fix.

Veeam Backup and Replication software is a very popular Virtual Machine backup software at the moment. It is very robust and offers a lot of options for backing up and moving your virtual infrastructure off site.

Recently after setting up the software I discovered that after about 11 hours of a restoration processing of a 4TB MSSQL vm backup the software would hang and the restore would fail.

After about 3 weeks of back and forth with Veeam support and digging into the software my entire infrastructure and even my SAN. The developers came back with a registry entry fix that prevents the software from hanging on restore. This registry needs to be added to the Veeam Server,  Veeam Proxies, and Veeam Repositories.

Essentially you need to add this to any and all installations of Veeam in your infrastructure. Then all you do is Restart the Veeam Transport Service, named Veeam Data Mover Service. Alternatively reboot any and all servers.

The registry entry you need to add is as follows;

name: HangedAgentKillTimeout
path: HKLM\SOFTWARE\Veeam\Veeam Backup Transport
type: REG_DWORD
value: 28800

You can also put the following in a batch file if you’d like.

Reg Add “HKLM\SOFTWARE\Veeam\Veeam Backup Transport” /v HangedAgentKillTimeout /t REG_DWORD /d 28800