January 9, 2022

AdGuard Home on Ubiquiti Cloud Key: Update

I have noticed that a couple of things has changed since those original installation instructions were written in the reddit post I have referred to earlier:

  • If you have SD card installed, it is now mounted under /sdcard;
  • If you disable systemd-resolved service as recommended, CloudKey wouldn't boot. More specifically, the unifi-core service would go fail to launch.

Here are the updated steps which take these two issues into account.

# 1: Download and unpack adguard
cd /tmp
wget https://github.com/AdguardTeam/AdGuardHome/releases/latest/download/AdGuardHome_linux_armv7.tar.gz
tar -xzf AdGuardHome_linux_armv7.tar.gz
mv /tmp/AdGuardHome /opt/adguard
rm AdGuardHome_linux_armv7.tar.gz

# 2: Make var directory
mkdir /var/opt/adguard
ln -s /var/opt/adguard data

# 3: Turn off systemd-resolved
cp /etc/resolv.conf /tmp
systemctl stop systemd-resolved
systemctl disable systemd-resolved.service
unlink /etc/resolv.conf
mv /tmp/resolv.conf /etc

# 4: Run initial setup
# Open http://[ip]:3000, change admin port, hit Ctrl+C when done

# 5: Setup as a service
./AdGuardHome -s install
systemctl status AdGuardHome.service
# Done. Open http://[ip]:[port].

# 6: Backup config
mkdir /sdcard/backup
cp /opt/adguard/AdGuardHome.yaml /sdcard/backup/AdGuardHome.yaml
Posted by Vadim at 12:41 PM | Comments (0) | TrackBack (0)

November 1, 2021

AdGuard Home on Ubiquiti Cloud Key

I have been running a filtering DNS instance on my Synology for a while as described by Gerzon on his blog, which originally was detailed on old Synology forums - but those URLs no longer work. This set up was running fine. I have used this DNS instance to host records for internal network, and I could always add some one-off blocks to it as well on as-needed basis. But I wasn't keeping it up-to-date with filter list updates, and so I was looking for a way to automate the update process.

While looking for alternative solutions (such as PiHole) I have and stumbled upon AdGuard Home package, which looked exactly what I needed, and more, with features as per-client configuration. So I have decided to give it a whirl, and install it on another host - to keep existing set up running just in case I needed a backup. UniFi Cloud Key Plus was a target for my AdGuard set up, and it was a breeze. A Reddit user has described installation steps here. With differences being, I have not yet installed a Micro SD card into Cloud Key, so I have installed it into /opt/adguard, and stored AdGuard's data in /var/opt/adguard.

mkdir /opt/adguard && cd /opt/adguard
# unzip adguard here
mkdir /var/opt/adguard
ln -s /var/opt/adguard data
# proceed with install steps

That's it! Now I can have it all: nice UI with DNS query logging capabilities, benefits of auto-updating filters, and per-client control over devices on my network on top of that. 🎉

Posted by Vadim at 5:23 PM | Comments (0) | TrackBack (0)

October 16, 2021

Aperture on macOS Big Sur 11.6

Thanks to the Tyshawn's Retroactive app, it is still possible to run Apple's Aperture app on the latest macOS versions. At the moment, I'm running Aperture on macOS Big Sur 11.6 with the help of Retroactive 1.9. It even comes with extensive deep dive article explaining how it came together. Neat!

While Retroactive has a couple of issues - primarily I see that thumbnails don't refresh as quickly and reliably as they are supposed to - but it is still pretty much usable. One issue I have noticed which wasn't mentioned is it seems that the Aperture's login item responsible for updating iCloud's photo stream has stopped working, and macOS repeatedly tries to re-open it every 10 seconds... That doesn't sound optimal.

Oct 9 00:01:16 iMac com.apple.xpc.launchd[1] (com.apple.photostream-agent[99515]): LaunchServices returned a bundle URL that does not match with the LoginItem's known association.
Oct 9 00:01:16 iMac com.apple.xpc.launchd[1] (com.apple.photostream-agent[99515]): Service exited with abnormal code: 78
Oct 9 00:01:16 iMac com.apple.xpc.launchd[1] (com.apple.photostream-agent): Service only ran for 0 seconds. Pushing respawn out by 10 seconds.

Since I am not using iCloud with Aperture, my solution was simply to disable it.

launchctl disable com.apple.photostream-agent
launchctl remove com.apple.photostream-agent

This does not stop macOS from loading it next time you reboot your mac. So to prevent it from loading next time, I've also hidden it from the OS.

cd /Applications/Aperture.app/Contents/Library/LoginItems
sudo mv PhotoStreamAgent.app PhotoStreamAgent.app.disabled
sudo chmod 700 PhotoStreamAgent.app.disabled

That was it.

Posted by Vadim at 2:19 PM | Comments (0) | TrackBack (0)

June 29, 2021

Independent watchOS Apps

Speaking of watchOS apps, it looks like developing a full fledged application running entirely on watchOS is not yet possible: there is no networking to speak of on watchOS. 😔

If you need anything beyond basic HTTP or CloudKit, the only option is to use WatchConnectivity framework to funnel all networking through the extension running on the iPhone. 😢

The only hope is that it will be added in the future.

Posted by Vadim at 6:40 PM | Comments (0) | TrackBack (0)

June 13, 2021

Finishing Failed Transactions

On the topic of regressions in minor iOS updates, there was another one a bit ago on iOS 13.4 release, as I recall. That one was in the StoreKit API, and it has changed the way how failed transactions are being processed.

Normally, you have to finish every transaction passed into your SKPaymentQueue delegate once you are done processing it, and that includes failed transactions. However that wasn't the case on iOS 13.3 and earlier releases: failed transactions did not require finishTransaction: call and were removed from the queue even if they were not acknowledged.

Starting with iOS 13.4 though, you have to acknowledge all transactions.

[[SKPaymentQueue defaultQueue] finishTransaction: transaction];

Posted by Vadim at 11:31 AM | Comments (0) | TrackBack (0)

May 4, 2021

OpenSSL on Apple Watch

I needed OpenSSL library for the project I've been meaning to start for Apple Watch. So I've checked in all the usual places, and found out that one wasn't made available yet, so I thought I'd take that on myself.

That meant compiling it for watchOS platform, and four different architectures: armv7k and arm64_32 for device, and x86_64 and arm64 for the Simulator. That last one is a new addition in Xcode 12 to support new M1 Macs. I don't have one yet, but it would help to prepare for the future.

And that presents first problem. Earlier, before M1 arrived, it was possible to combine a library built for, say, iOS platform on arm64 architecture with library built for iOS Simulator on x86_64 into single Mach-O universal binary (or "fat library"), and Xcode was able to figure out which one goes where, even though universal binary does not identify platforms for each included architecture. Now with both M1 and iOS devices running on arm64 architecture, we have two platforms with the same architecture, and it is not possible to create such universal binary at all.

So the solution is to create separate "fat libraries" for each individual platform. That means separate library for:

  • iOS,
  • iOS Simulator,
  • tvOS,
  • tvOS Simulator,
  • watchOS,
  • watchOS Simulator,
  • ... and Catalyst, of course.

This presents second problem. Previously, you'd just drop single libcrypto.a (and libssl.a, if needed) into your project, and call it a day, but now you have to figure out how to make Xcode use one file, libcrypto-iOS.a, on device, and another, libcrypto-iOS-Sim.a, on Simulator.

Solution to the second problem is new XCFramework framework format. It combines libraries for all of these platforms (and corresponding header files) into single directory, and then Xcode magically picks just the right library automatically. 🎩 It can be easily created using xcodebuild by passing it a few parameters.

Resulting script is available on GitHub, and there is also a pull request against parent repository. And below is requisite screen shot of OpenSSL library running on watchOS as a proof that it works:


Posted by Vadim at 6:59 PM | Comments (0) | TrackBack (0)