HOME GARDENING AND HOUSEHOLD LIFE
Use NSSavePanel in Swift
TL;DR:
@IBAction func browseDirectory(_ sender: Any) { let dialog = NSSavePanel() dialog.title = "Save file" dialog.showsResizeIndicator = true dialog.canCreateDirectories = true dialog.showsHiddenFiles = true dialog.allowedFileTypes = ["txt"] if (dialog.runModal() == NSApplication.ModalResponse.OK) { let result = dialog.url if (result != nil) { let path = result!.path // Do stuff with 'path' variable } } else { return // User clicked cancel } } Don’t forget to allow the app to access the filesystem. --- Okay, we need to make a dialog, so let’s make a variable named dialog and assign it the NSSavePanel. let dialog = NSSavePanel() Then we have to set some parameters. Let’s give the dialog a title-bar name. dialog.title = "Save file" The parameter names are pretty self-explanatory, but these options are for showing the “resize” button in the title bar, allowing users to create new folders, and showing hidden files. dialog.showsResizeIndicator = true dialog.canCreateDirectories = true dialog.showsHiddenFiles = true If you want to restrict users so that they can only select certain files: dialog.allowedFileTypes = ["php"] We then expose the dialog to the users: if (dialog.runModal() == NSApplication.ModalResponse.OK) { let result = dialog.url if (result != nil) { let path = result!.path // Do stuff with 'path' variable } } else { return // User clicked cancel } Great, so we’re done now, right? Not so fast! If you run your app now, it will crash. What gives? Well, you forgot to allow the app access to your filesystem! Simply click on your project on the left sidebar, press on your app under the smaller sidebar with the title-name “Targets”, choose “Capabilities” on the top bar, and then choose Read/Write under “User Selected File”. You should now have a functional save panel!INTERNATIONAL RELATIONS AND TRADE
Set up a network wide VPN using Ubuntu Server
As a foreigner living in China, you crave Netflix and YouTube, but hate toggling over to your VPN app over and over just to watch censored content. So waht’s the solution? Enter the network-wide VPN gateway - your very own server that you will set up to tunnel your entire home’s network! # Prerequisites You will need: - A VPN provider that gives out OpenVPN configurations. Other protocols will probably also work, but they are not covered in this tutorial. - A server or a VM running Ubuntu Server. Using the latest version is recommended. I used 16.04 LTS at the time of writing this blog post. - Some Linux and networking knowledge - (optional, but recommended) A router that supports setting the default gateway in the DHCP server Without proper Linux and networking knowledge, you will have a broken LAN someday with no way to troubleshoot or debug! Make sure you know what you are doing before following this tutorial. A router that supports setting the default gateway on the DHCP server is important. Without it, you will have to manually go around each device and set up the proper configuration so it’ll route the traffic through your new Linux router! At that point, you might as well set up the VPN on each device, but the benefit of setting this up at all without a supported router is still great that you should consider setting it up anyway. Some devices that do not support native VPN (such as the Chromecast, Roku Fire sticks, your smart robot cleaner) will now connect through the VPN through a simple configuration change. So whether you’re serious about this, or it’s just a fun experiment, it’s definitely worth it to set it up. Just understand the risks before you move on. If any problems arise, you should be able to debug them. # VPN setup Grab the OpenVPN file from your VPN provider. The page should also list your unique username and password for OpenVPN. Grab that too. (NOTE: If it does not show your unique username and password, then it might be your VPN provider’s account username and password. Experiment and see if it works.) Now, depending on your VPN provider, they will give you one, in-line OpenVPN file, or separated files consisting of the client keys and server certificates. The former is better, since you won’t have to monkey around with key configurations. Jumping onto your VM, execute this command:
ifconfig This will show your current network configuration. Note down the interface name on the left side. For example, my network was: enp2s0 Link encap:Ethernet HWaddr <obfuscated> inet addr:192.168.0.100 Bcast:192.168.0.255 Mask:255.255.255.0 <truncated> lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 <truncated> Some things to note here. First, your Ethernet interface is enp2s0, and your IP address is 192.168.0.100. These will be important later on. Now, let’s install OpenVPN: sudo apt install openvpn Once it’s installed, let’s configure it. Copy the sample configuration file: sudo cp <VPN name here>.ovpn /etc/openvpn/<VPN name here>.conf At this point, if you have keys included with the .ovpn file, look at the keys. They will be named like ca.rsa.2048.crt or similar, depending on what key size your VPN provider uses. Simply find the key files and copy them with this command: sudo cp ca.rsa.2048.crt crl.rsa.2048.pem /etc/openvpn If your provider is smart enough to provide inline certificate files (OpenVPN configuration files that have the certificates attached inside), you can skip the above command. Continue down below. Now you might be wondering why we renamed that .ovpn file to .conf. It’s because this is the only way we can use systemd to control OpenVPN. With this change, the configuration file gets registered to systemctl, and you can enable them with OpenVPN@VPN-name-here. Next, note down your VPN username and password in /etc/openvpn/login: username-here password-here An example credential file would be something like this: ericswpark examplepassword12345 Save and exit. Now edit /etc/openvpn/<VPN name here>.conf and look for the following line: auth-user-pass Change it to: auth-user-pass /etc/openvpn/login Now, if you have separate key files copied from above, you will need to do one more step. Find these lines: ca ca.rsa.2048.crt crl-verif crl.rsa.2048.pem And change them into: ca /etc/openvpn/ca.rsa.2048.crt crl-verif crl.rsa.2048.pem And you’re done! Before you save, there’s some additional options you might want to configure. For example, you might want to disable persist-tun if you live in an environment where Internet connection is flaky. The VPN will destroy the tunnel interface when it restarts, forcing it to use your regular censored Internet for the VPN server lookup. This is handy because the VPN server lookup will fail over a dead tunnel interface. Find this line: persist-tun And put a # in front of it to disable it: # persist-tun If you want the server to keep the connection alive, find or add these following two lines: keepalive 10 30 resolv-retry infinite The last line isn’t strictly needed, because the default is infinite. The first line tells the OpenVPN client to ping the server (--ping) every 10 seconds, and restart (--ping-restart) if there is no response for 30 seconds. This has been handy because the Great Firewall of China likes to send TCP RST packets everyonce in a while. Experiment with those values if you need a more reliable connection, but I’ve found 30 seconds is pretty adequate for a smooth network drop fix without unnecessarily straining the VPN server. Save and now, we’ll have to test the VPN server. Since I’m in China, that’s super easy! Just ping Google. If you’re in a different country where that test is inconclusive, you could check ifconfig again. Start the client: sudo openvpn --config /etc/openvpn/<VPN name here>.conf If you see Initialization Sequence Completed anywhere in the logs, congratulations! Your VPN is set up correctly! Press Ctrl-C to destroy the VPN tunnel and follow along with next steps. # Setting up a static IP (optional, but recommended) At this point, you might want to set up a static IP for your VM. This is because you don’t want IPs shifting if you decide to add the IP to your default gateway settings in your router. Log into your router administration page. The details should be underneath the router, printed out on a sticker. If you can’t find it, then just Google your router’s manufacturer and look for the IP. If that doesn’t work, check your computer’s default gateway, because usually routers push their IP through there. If all else fails then just type in addresses like 192.168.0.1 or 192.168.1.1. If you find the IP, remember to write it down because it’ll be important later, and click on DHCP address reservations, or something named similar. Remember your MAC address from step 0? No? Then just do ifconfig again and jot down the MAC address for your Ethernet interface. Assign it an address, then press OK. Remember that address, Now some more configurations on your VM! Edit this file, /etc/network/interfaces and find the lines: auto enp2s0 iface enp2s0 inet dhcp The interface name might be different. Just change it so that it looks like this (remember to keep the interface name that was in your file, NOT the ones shown here!): auto enp2s0 iface enp2s0 inet static address 192.168.0.100 netmask 255.255.255.0 gateway 192.168.0.1 dns-nameservers 1.1.1.1 1.0.0.1 You’re free to use any DNS nameservers you like. Personally, I like the new CloudFlare 1.1.1.1s. Remember to input the correct IP address and netmask! The IP address is the one you manually assigned on the router administration page, the netmask can be found by checking your network settings, and the gateway should be whatever it was before (check network settings on your computer) or your router’s administration IP, which is usually the default gateway on most routers. The default gateway bit is important, because if you decide to forward the VM’s IP as the default gateway later in the DHCP push settings, your VM box will have a default gateway value set to itself. So make sure the default gateway is the current default gateway shown in your network settings. Cool! Reboot the VM and the router and make sure both are accessible, and your Internet is working. Next! # Setting up the tunnel First, let’s enable the OpenVPN service so it starts at boot. sudo systemctl enable OpenVPN@<VPN name here> Don’t write the .conf extension when you’re running this command! Then, let’s enable IPv4 forwarding. Edit this file - /etc/sysctl.conf - and find this line: # net.ipv4.ip_forward = 1 Change it to: net.ipv4.ip_forward = 1 Just remove that #, save and move on. Next, reload sysctl! sudo sysctl -p Congratulations! Now we need to configure the firewall and routing. # iptables This part is extremely hard, probably the hardest in this tutorial. I don’t even understand most of it, but will try to explain it as best as I could. First off, we want to allow the loopback traffic through the loopback device. Execute these two commands: sudo iptables -A INPUT -i lo -m comment --comment "loopback-input" -j ACCEPT sudo iptables -A OUTPUT -o lo -m comment --comment "loopback-output" -j ACCEPT Then, we want to allow traffic coming in from the network, and traffic going out to the tunnel network. (If you don’t know these or forgot from earlier, run the VPN using the command way above, and run ifconfig to figure out the interfaces.) Execute these commands, making sure to substitute the interface names from earlier: sudo iptables -I INPUT -i enp2s0 -m comment --comment "Local network" -j ACCEPT sudo iptables -I OUTPUT -o tun0 -m comment --comment "VPN network" -j ACCEPT Then we need to allow the OpenVPN traffic to pass through the box. Find the port number by looking at the .conf file we talked about earlier. It should be on the line that starts with remote. Then execute this command, making sure to replace that port number and interface name: sudo iptables -A OUTPUT -o enp2s0 -p udp --dport 1194 -m comment --comment "OpenVPN traffic" -j ACCEPT Next up, we need to allow certain services to operate. Execute these commands: sudo iptables -A OUTPUT -o eth0 -p udp --dport 123 -m comment --comment "NTP service" -j ACCEPT sudo iptables -A OUTPUT -p UDP --dport 67:68 -m comment --comment "DHCP service" -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p udp --dport 53 -m comment --comment "DNS service" -j ACCEPT Almost there! You need to forward the traffic from the tunnel to the Ethernet interface. This bit is really important! Run these commands (and make sure to substitute the interface names): sudo iptables -A FORWARD -i tun0 -o enp2s0 -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i enp2s0 -o tun0 -m comment --comment "Local network to VPN" -j ACCEPT Cool, one last thing. You need to set up MASQUERADE on the POSTROUTING table on your NAT, so that the Network Address Translation works across the VPN. Execute the final command (switch these interface names, remember): sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE If you managed to follow this far, congratulations! But before you go and celebrate, you want to save these configurations so these don’t get lost over a reboot. Run this: sudo apt install iptables-persistent And the installation will begin. If it asks you if it should save the current configuration, choose yes, and carry on. Let’s enable the service to run at boot: sudo systemctl enable netfilter-persistent If, in the far future, you add any more iptables rules, you can save them by running: sudo netfilter-persistent save And they will be saved. One last, really important thing. If you want to back up these configurations, you can type: sudo iptables-save > backup.txt To save the rules inside a text file. This is also a handy way to edit these configurations should you decide to change them. Once you want to restore, use this command: sudo iptables-restore < backup.txt Nice! Your configuration is nearly finished! # Test the connection Reboot the box. On the client device you want to test, change the default gateway’s IP address to the VM’s IP. It should start forwarding traffic through the VPN! Congratulations! But this is tedious. I’m lazy. What should I do? # Set up router forwarding If your router supports default gateway switching, you can do this. (Most routers support this) Go to the router administration page (remember it?) and click on DHCP settings. Under the Default Gateway IP address, input the VM’s IP. Now reboot the router. If it works, great! In odd cases, the default gateway change might actually just change the administration page’s IP address. If that happens, there will be an address collision, and your VM box will either lose the IP address or lose access to the local network. In severe cases your router administration page might not come up. In that case, just disconnect the VM box, reboot the router and connect to the administration page to change the default gateway back. If this is the case, then your router does not support default gateway switching. # Connection-helping script Now, since China is great for these TCP RST packets that drop your VPN connection sporadically (so you have to remote into your VM and fix it), I wrote a Python script that helps me out with the entire process. Any improvements in the form of pull requests would be welcome!CHINA
CLIMATE CHANGE
Force git to sign your commits
Since GitHub puts a nice shiny “Verified” next to your commits if you sign them with GPG, you might be wondering how to get on this bandwagon. Not to worry! With this one simple trick, you’ll never have to remember to type
git -S, ever again! Run the following (substitute your key in the second command): git config --global commit.gpgsign true git config --global user.signingkey <KEYHERE> Did you forget your GPG keys? gpg --list-keys --keyid-format short Alternatively, check out my comprehensive GPG guide. # Troubleshooting If git fails to sign your commit with the following error: error: gpg failed to sign the data fatal: failed to write commit object This is usually due to gpg not being able to find the current shell to launch the password prompt on. To fix this problem, append the following line in your ~/.bashrc or ~/.zshrc, depending on what shell you use: export GPG_TTY=$(tty) I’ve also seen this error occur on Visual Studio Code if the terminal window’s height is too small for the prompt. Resize the terminal to be longer and it should fix the problem. ## Windows If you are using GPG4Win to manage your GPG keys, you may need to run the following line in the terminal as well: git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe" This makes git use GPG4Win’s gpg.exe executable instead of the one bundled with Git for Windows.HOME GARDENING AND HOUSEHOLD LIFE
Bypassing NAT with reverse SSH tunneling
# Problem I had recently moved to China, where I discovered that the carriers used CGNAT to combat the growing problem of shrinking IPv4 assignments. No surprises there, since China is literally booming with people. However, this posed a big problem for my home server and network, since in Korea I had my very own public IP address handed out to me. But there is always a solution - and this time, the solution came in the form of SSH. Using SSH, I could forward literally any ports I wanted, from my local network, to a remote server that did have a public facing IP address. In this tutorial, I’ll go over how to get your own remote server set up, and tunnel your very own home server to a remote server so that you could access it from anywhere. # 1. DigitalOcean You need a remote server to get started. I chose a VPS, because it is simple and easy to just spin up an instance. Hop onto DigitalOcean, make an account, link a credit card, and spin up an instance. Size doesn’t really matter - I chose the smallest instance on there, which is $5 a month. Note down the IP address of your instance. From now on, I will be expressing this IP as
XXX.XXX.XXX.XXX. # 2. Server setup Connect to your server using ssh. Do any server-maintenance stuff you need to do. I recommend this quick start article from DigitalOcean to add a sudo user to your server. After you’ve set up your server and secured it enough, proceed to the next step. I won’t be going into detail on server hardening, because that’s a topic for another day. Then, you want to modify /etc/ssh/sshd_config, assuming you chose Ubuntu when you set up your VPS instance. Inside there, find the line named #GatewayPorts no and change it to GatewayPorts yes(remove the hash in the front and change no to yes.) Save, exit, and type sudo service sshd restart. In theory you shouldn’t get kicked off from the server, but if you do, just reconnect. Finally, restart the server. # 3. Client setup Let’s say you have a port you want to forward on localhost, port 9000. You want to make it so that when you connect to the remote server, you could access it on port 80. Client –> Remote server XXX.XXX.XXX.XXX (port 80) –> Home Server –> Web instance (port 9000) To do that, on the home server type this SSH command: ssh -nNT -R 80:localhost:9000 username@XXX.XXX.XXX.XXX Let’s dissect this command. ssh is the program name itself, -nNT instructs SSH to not create a TTY instance (so you will NOT get a Terminal prompt), -R tells SSH we want to make a remote port forward, 80 is the port the remote server will be listening on, localhost is the IP the home server will forward requests to (in this case, it’ll be itself), 9000 would be the port that the home server would listen on, and the rest (username@XXX.XXX.XXX.XXX) is just the typical SSH details to connect to a server. Boiling all this down to a practical example, I have a instance with an IP address of 192.168.0.102 on my local network, such as a Raspberry Pi. It is listening on port 12984 and is hosting a web server. I want to see my website pop up when I connect to the remote server, so we would have to use port 80 or even port 443. To access this through a reverse tunnel, I would have to use this command on my home server: ssh -nNT -R 80:192.168.0.102:12984 username@XXX.XXX.XXX.XXX # HTTP ssh -nNT -R 443:192.168.0.102:12984 username@XXX.XXX.XXX.XXX # HTTPS ssh -nNT -R 80:192.168.0.102:12984 -R 443:192.168.0.102:12984 username@XXX.XXX.XXX.XXX # or all in one And this would be the diagram for how it would work: # 4. AutoSSH Sure, you could type these commands out every time you want a bridge! But personally, I’m lazy, and I want a script that does it for me every boot. That’s where AutoSSH comes in. sudo apt install autossh Change to fit your distribution. In this case, I’m using Ubuntu Server. Then, we need to make a systemd configuration file. nano /etc/systemd/system/autossh-tunnel.service Paste the following in, adapting it for your use: [Unit] Description=AutoSSH tunnel service After=network.target [Service] Environment="AUTOSSH_GATETIME=0" ExecStart=/usr/bin/autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o "ExitOnForwardFailure yes" -N -R 80:192.168.0.1:80 -R 443:192.168.0.1:443 root@server.example.com -p 22 -i /home/example/.ssh/private-key [Install] WantedBy=multi-user.target Then tell systemd to look for new configuration, and then enable the configuration: sudo systemctl daemon-reload sudo systemctl start autossh-tunnel.service sudo systemctl enable autossh-tunnel.service If you want to configure how SSH connects to the server, you could utilize ~/.ssh/config: Host example-tunnel HostName server.example.com User example Port 22 IdentityFile ~/.ssh/private-key RemoteForward 80 192.168.0.1:80 RemoteForward 443 192.168.0.1:443 ServerAliveInterval 30 ServerAliveCountMax 3 ExitOnForwardFailure yes You don’t really need to specify RemoteForward here since AutoSSH will take care of that for you anyway, but I just put it there for peace of mind. For more information, you could check out this great guide over here. I learnt a lot from that post, so thanks to the authors of that guide!CHINAKOREA
CYBERSECURITY AND DIGITAL PRIVACY
Setting up Duplicacy on UnRAID with Backblaze B2
In this post we’re going to look at Duplicacy, a tool that allows you to backup large amounts of data to any storage provider. # So what is Duplicacy? Duplicacy is a backup/restore tool for servers. They have a free CLI version and a paid GUI version, but you probably only need the CLI tool unless you’re extremely scared of the terminal. # Big warning before we begin - Duplicacy expects sole access to the backup destination. That means, if a backup is running and you issue a prune command on another server, it may result in a loss of ALL of your data! Always make sure that only one instance of Duplicacy is operating at a given moment. - RAID is not a backup. If someone tells you they have a bulletproof backup solution with RAID only, you have the right to laugh in their face. - If you can’t restore it, you don’t have it. If you have everything stored on Amazon Glacier and your house burns down, you’ll probably spend all your money on a new house, not for downloading your music stash from Glacier. Always make sure the backup is in an easily-accessible medium and make sure to test your backup so that you don’t have trouble restoring it later. Onto the guide! # Steps to install Now, UnRAID boots off of USB drives, which means that if you just blindly copy your Duplicacy executable to a system folder, the changes will be lost on next boot. So we need to install Duplicacy on a persistent partition, and then copy it across. Navigate to your USB drive on your UnRAID server:
cd /boot/config/plugins Download the Duplicacy executable: wget -O duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v2.2.3/duplicacy_linux_x64_2.2.3 Now it’s very certain that there is a new version by the time you are reading this article. Simply go to the releases tab on GitHub, right click on duplicacy_linux_x64_xxx where xxx is the version number, and select “Copy link location” (may vary depending on browser). Then paste it after wget -O duplicacy. Then, make the necessary changes in your go file to copy over the executable on every boot. Type the following two lines at the end of /boot/config/go: # Copy duplicacy ln -s /boot/config/plugins/duplicacy /usr/local/bin/ This should symlink the executable to an executable location every time UnRAID starts up. You’re done! Reboot the machine (or run ln -s /boot/config/plugins/duplicacy /usr/local/bin/) and make sure you can run duplicacy -h in your terminal. # Setting up a Duplicacy “repository” You need to get Duplicacy to init a new “repository”. This means you’re marking what you want to back up. Duplicacy will create a new hidden folder called .duplicacy in your current directory. duplicacy init repositoryname b2://servername-duplicacy -e So what does this mean? Let’s go over this: - Let’s say we’re currently in /mnt/user, so we’re backing up everything underneath it. For example, Duplicacy will back up /mnt/user/Movies, /mnt/user/Music, and so on. - init tells Duplicacy we want to set up a repository here. - repositoryname is just a name you will give to the repository. Set it to whatever. - b2:// is the protocol (Backblaze B2). You can use other protocls if you use different providers, such as sftp:// and so on. - servername-duplicacy is the bucket name you have in B2. You should already have this created before running the command! - -e tells Duplicacy to encrypt the backups. You can actually set up duplicacy in the root folder of your shares, /mnt/user/*. This way, duplicacy stores all the configuration and other details in /mnt/user/.duplicacy/*. # Stop Duplicacy asking for keys The next step to automation is to get Duplicacy to stop asking for your application ID and password all the time. Otherwise, you will need to manage them yourself every time you back up, which will not work in an automated environment. Caution: If you go through with these commands, then your application keys and encryption password will be stored as plain-text inside your .duplicacy folder. Anyone with access to this folder will be able to see your keys. Only issue the following commands if you are certain that only you will have access to the server. Run the following commands: duplicacy set -storage b2://servername-duplicacy -key b2_id -value b2_id_here duplicacy set -storage b2://servername-duplicacy -key b2_key -value b2_key_here duplicacy set -storage b2://servername-duplicacy -key password -value encryption_key_here # Excluding folders and files You may want to customize the filters file in .duplicacy/ before running the backup. Personally, I have mine set to exclude Docker volume folders, VM folders, and the Docker image (since they can always be recreated with no loss). For the full documentation, refer to the official documentation since I don’t know regular expressions yet. Here is my UnRAID filters file if you are interested: -appdata/ -backup/ -VM/ -Downloads/ -ISO/ -docker.img -libvrt.img # Automating backups You’re almost there! We need to automate backups with User Scripts, since we all know you won’t manually remote every day to issue the command. Download User Scripts (plenty of guides online) on your UnRAID server. You can use Community Applications for it. Once you’re there, create a script with the following: #!/bin/bash # https://stackoverflow.com/a/185473/1388019 lockfile="/tmp/duplicacy.lock" if [ -e ${lockfile} ] && kill -0 `cat ${lockfile}`; then echo "duplicacy already running" exit fi # make sure the lockfile is removed when we exit and then claim it trap "rm -f ${lockfile}; exit" INT TERM EXIT echo $$ > ${lockfile} # run the backup with default settings cd /mnt/user /usr/local/bin/duplicacy -log backup -threads 2 -stats # clean up lockfile rm -f ${lockfile} Let’s go over this line by line. On the first couple of lines, from the line that starts with lockfile to echo $$, we set up a lockfile. In case User Scripts mess up and run the script twice (again, two instances of Duplicacy running can seriously corrupt the backup), the lockfile prevents the script from running. Then the two lines after that start the backup, with 2 threads. Adjust to match your CPU. -stats just shows you what it’s backing up at a given moment. Save it with an appropriate name and description, set a schedule, and let it run in the background! The backup is now completely automated! # Deleting old backups By the way, Duplicacy will not automatically delete old backups. To do that, you must prune your backup set. Add the following two lines in the original script, before the “clean up lockfile” section: # Delete any backups older than 120 days. Adjust if required duplicacy prune -exhaustive -exclusive -keep 0:120 This deletes any previous data backups older than 120 days. Adjust the date if necessary. # How do I restore? I’m not sure because my server hasn’t crashed yet. (knock on wood) If it ever does I will update this section. But it should just be a matter of running something like duplicacy restore in the root directory after restoring your configuration files. # To uninstall 1. Delete the executable over at /boot/config/plugins/duplicacy. 2. Edit the go file over at /boot/config/go. Remove the two lines that we added above. 3. Delete configuration files if required. Go to your source directory (for me it’s /mnt/user) and then delete the .duplicacy directory. 4. Remove the User Scripts. Once that’s done, reboot your UnRAID server.