Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation about installing on Android #2269

Open
emanruse opened this issue Dec 29, 2022 · 48 comments
Open

Documentation about installing on Android #2269

emanruse opened this issue Dec 29, 2022 · 48 comments

Comments

@emanruse
Copy link

Here is my experience with 'dnscrypt-proxy' on Android (I use Replicant. Replicant has root and init.d support "out of the box".

To start off, I have spent more than a week digging the web for information on how to do it. I have read many many discussions, questions and answers (including issues here). The official documentation didn't really help. In the very beginning it says:

If you want to change the DNSCrypt resolver, unzip the downloaded archive, edit the RESOLVER_NAME variable in system/etc/init.d/99dnscrypt. Keep the content as a ZIP file, with the original structure.

I have downloaded and unzipped every single release since 2.0.6 (the first one introducing Android binaries). There is no 99dnscrypt in any of them. Neither there is such file in the source code in git. So, my next step was to search the web, read issues here and there, a lot of time and effort.

What I found:

  • @Quindecim's repo - it seems made for some software called Magisk. I don't want to install additional software which I don't need, give it permissions etc. I just want dnscrypt-proxy.
  • There are some solutions for creating a boot service using init.rc. This process seems to involve unpacking the boot image, editing init.rc, and repacking it. This is new to someone like me. I found several softwares/versions which unpack and repack but when testing unpacking and repacking with no modification whatsoever the repacked image is always quite smaller than the original. I decided not to risk bricking my phone, so I stopped exploring this route.
  • Researching further, I found this issue and from it - @uzen's repo. Unfortunately, it seems to include a binary with unknown source code in src/META-INF/com/google/android, so I won't run it. Instead of putting that blindly on my phone, I looked into the 99dnscrypt it includes and the two sub-scripts it calls. My impression: the author has spent quite some time on that. Shellcheck complains about so many problems though. Regardless of that, I decided to give these 3 scripts a try but unfortunately the result wasn't satisfactory. I couldn't get things to work as expected, so after many hours of digging into that obviusly old shell script code, I decided to return to simplicity and start from scratch.
  • Then I found this. The init.d script used by the questioner is pretty much the same one which I tried myself initially. The difference is that I don't get the errors he gets - there are no such selinux messages in my logcat.

The official documentation also suggests installing one of "four (paid) apps" to switch currently running DNS settings to DNSCrypt. That is another thing I don't want to do. Installing additional (especially non-free) software for the sake of improving security through a software like dnscrypt-proxy, thus increasing attack surface and so on, is a logical contradiction.

So, in my search for a simple, clean, and working FOSS solution I used the same steps as in the Stackexchange question. In my dnscrypt-proxy.toml I enable blocked_names and put only one line in it for testing:

*.fsf.org

My findings:

I notice that 'dnscrypt-proxy' is started twice on boot:

$ adb shell logcat | grep dns
12-29 19:25:23.100  1993  1993 I sysinit : Running /system/etc/init.d/99dnscrypt 
12-29 19:25:23.290  2006  2006 I dnscrypt: Starting dnscrypt-proxy... 
12-29 19:25:23.315  2010  2010 I dnscrypt: Changing dns with iptables... 
12-29 19:27:38.500  3459  3459 I sysinit : Running /system/etc/init.d/99dnscrypt 
12-29 19:27:38.550  3464  3464 I dnscrypt: Starting dnscrypt-proxy... 
12-29 19:27:38.595  3467  3467 I dnscrypt: Changing dns with iptables...

$ adb shell ps | grep dns
root      2009  1     813640 6500  futex_wait 40103db0 S dnscrypt-proxy
root      3466  1     808256 7628  futex_wait 4016fdb0 S dnscrypt-proxy

The 'iptables' rules are not applied:

root@i9300:/ # iptables -L | grep 53                                               
1|root@i9300:/ # iptables -t nat -L | grep 53                                      
1|root@i9300:/ # 

I kill 'dnscrypt-proxy' manually:

$ adb shell
root@i9300:/ # killall dnscrypt-proxy                                              
root@i9300:/ # killall dnscrypt-proxy                                              
killall: dnscrypt-proxy: No such process

Then I start the service manually (cellular data is not enabled):

root@i9300:/ # /etc/init.d/99dnscrypt                                            
root@i9300:/ # [2022-12-29 19:36:20] [NOTICE] dnscrypt-proxy 2.1.2
[2022-12-29 19:36:20] [NOTICE] Network not available yet -- waiting...

Now, 'logcat' and 'ps' show there is only one runnig process:

12-29 19:36:19.860  5209  5209 I dnscrypt: Starting dnscrypt-proxy... 
12-29 19:36:19.970  5213  5213 I dnscrypt: Changing dns with iptables...

$ adb shell ps | grep dns
root      5212  1     812096 7604  futex_wait 401c4db0 S dnscrypt-proxy

The firewall rule is applied correctly too:

root@i9300:/ # iptables -t nat -L | grep 53                                      
DNAT       udp  --  anywhere             anywhere             udp dpt:domain to:127.0.0.1:53

Enable cellular data and watch what is happening in 'adb shell':

root@i9300:/ # [2022-12-29 20:08:31] [NOTICE] Network connectivity detected
[2022-12-29 20:08:31] [NOTICE] Now listening to 127.0.0.1:53 [UDP]
[2022-12-29 20:08:31] [NOTICE] Now listening to 127.0.0.1:53 [TCP]
...
// many other regular notices
...
[2022-12-29 20:09:45] [NOTICE] dnscrypt-proxy is ready - live servers: 32

Everything seems to work. Testing to confirm:

root@i9300:/ # host fsf.org
host: Host not found.
1|root@i9300:/ # host gnu.org
gnu.org has address 209.51.188.116

So, the blocked_names section works and resolving works.

Next, I disabled cellular data, unplugged the USB cable connected to the computer and connected the external WiFi adapter (Replicant needs an external RYF adapter as the phone's built in one won't work without proprietary software). So, I could not test with ADB any more but only using the limited "Terminal" application in Replicant and using the browser that comes with Replicant (no idea what its name is).

In that terminal (rewriting manually here):

host -v fsf.org
host: Host not found.
host -v gnu.org
host: Host not found.

and so on - it seem nothing resolved.

In the browser I see a different result though:

  • fsf.org works (although it must not resolve)
  • gnu.org works
  • other sites work

Obviously, things don't work as expected when using WiFi.

Connecting the phone to the computer again I see that 'dnscrypt-proxy' process is still active. Re-testing with cellular data again shows the same result as above: fsf.org is not resolved, other domains are.

The questions are:

  1. Why only the logging commands of the init.d script work, considering that the script is ran by root at boot time?

  2. Why (even with manual starting of the service) the behavior is different when using WiFi?

  3. How to make this service work on boot with all connections (cellular, WiFi, reverse USB tethering, etc) without requiring manual starting through ADB or additional apps (assuming one already has root and init.d support)?

It would be really great if someone can update the documentation.

Best wishes for the new year!

@jedisct1
Copy link
Member

Thanks for your input!

The documentation is a Wiki, so anybody can update it, including you :)

Unfortunately I don't have an Android device, so I have no idea about how this works.

@emanruse
Copy link
Author

emanruse commented Dec 30, 2022 via email

@jedisct1
Copy link
Member

Android binaries are built automatically by the CI system, like all other binaries.

@emanruse
Copy link
Author

emanruse commented Dec 30, 2022 via email

@jedisct1
Copy link
Member

But that automation must have been configured by somebody in order to work properly, right? Doesn't that mean that the person who did that understands how Android works?

The beauty of languages such as Go and Zig is that the only thing it takes to build a binary for a given target is to specify the name of the target.

So, that's what I did for different flavors of Linux, Windows, Android, etc. even though I only have a Mac and have no idea how Windows and Android work.

@MF-Debug
Copy link

@emanruse I suggest you to use Invizible Pro. It's much simpler to use imo.

@emanruse
Copy link
Author

emanruse commented Dec 30, 2022 via email

@syphyr
Copy link
Contributor

syphyr commented Dec 30, 2022

@emanruse

  1. the repo is large because it is storing prebuilt binaries of dnscrypt-proxy. The older android build environment does not support new versions of go, so I am using prebuilt dnscrypt binaries.

  2. getting it to work with my repo will require building the rom. There are required changes to the sepolicy and I added a switch in the developer options to turn dnscrypt off/on and also the ability to enable all traffic through tor. So, those additional commits are for the needed changes to other android repos used to build the rom.

  3. I am using root to run dnscrypt because the older version of android (cm-14.1) did not seem to work right when changing the user to anything other than root. Although, I have read people using newer versions of android can change the user to something with less privileges. I couldn't get it to work with other users on cm-14.1, but the added sepolicy domain should help prevent dnscrypt from doing anything it is not supposed to do.

  4. "on property" is looking for changes in the android props and performs actions when the props change. That is how the settings work to turn dnscrypt off/on.

  5. the method I am using adds dnscrypt as a service to android so that it gets special system privileges and does not get killed under low memory situations, which will happen if you start dnscrypt any other way on android. Using init.d is not the correct way to add a service, that is what the .rc file is for.

  6. Android.mk is what the android build system uses to know where to copy the files

@emanruse
Copy link
Author

emanruse commented Dec 31, 2022 via email

@syphyr
Copy link
Contributor

syphyr commented Dec 31, 2022

@emanruse

If you look at https://github.com/uzen/dnscrypt-android , this repo will help create a zip file which can be installed from recovery. This is probably the closest you can get to installing dnscrypt-proxy without building the ROM. This repo uses init.d, but it requires a helper application (Afwall) to launch dnscrypt-proxy with root privileges. So, if you use this method, you will need to have root installed on your ROM and you will also need to install Afwall in order to start dnscrypt to get around the sepolicy that would normally prevent dnscrypt from starting up.

@syphyr
Copy link
Contributor

syphyr commented Dec 31, 2022

I have created some dnscrypt-proxy installation packages to be installed from the recovery, so you can take a look at the file structure. But in order for this to work, you would also need to update the selinux policy and build your device's boot.img, or this will not work. The selinux policy is contained within your boot.img. Another way to fix the sepolicy is to use Magisk, but I have not tried using that. The changes required to the sepolicy for dnscrypt can be found in my first post.

NOTE: These zip packages do not support installing on A/B file systems

dnscrypt-proxy-arm64-20221231-1-signed.zip:
https://www.androidfilehost.com/?fid=4279422670115706958

dnscrypt-proxy-arm-20221231-1-signed.zip
https://www.androidfilehost.com/?fid=4279422670115706960

@syphyr
Copy link
Contributor

syphyr commented Dec 31, 2022

@syphyr
Copy link
Contributor

syphyr commented Jan 1, 2023

BTW, upon further investigation on running dnscrypt-proxy as a non-privileged user, I finally was able to get it working like this:
syphyr/dnscrypt_proxy_prebuilt@8e58401

@emanruse
Copy link
Author

emanruse commented Jan 1, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 1, 2023

Most custom recoveries for android understand a scripting language called Edify. The zip file contains all the files to be installed along with an Edify script that performs actions for the installation such as setting file permissions, etc. You could still do it all manually with adb, but that would get old since you would need to keep doing it over after each rom update. The zip file also contains a script for addon.d which backs up the installation files and restores them automatically on rom updates (just like gapps). Take a look on xda for examples of edify scripts.

Afwall is needed if you want dnscrypt-proxy to start up automatically on bootup. Afwall is capable of starting up automatically on boot and launch a custom script command as root to startup dnscrypt-proxy as well (running as root). If you are using selinux enforcing, then Init.d will not be able to launch dnscrypt-proxy with correct permissions unless additional selinux rules are added to create a new selinux domain for dnscrypt-proxy.

Androidfilehost is a trusted site for android world.

You may want to try a dnscrypt-proxy magisk module if you do not want to build the rom.

@emanruse
Copy link
Author

emanruse commented Jan 2, 2023 via email

@dapphp
Copy link

dapphp commented Jan 2, 2023

Hey @emanruse ,

I've been running dnscrypt-proxy on Android for 5+ years now and have gone through many iterations with it on various devices and OS's. I had similar preferences to you, wanting to run dnscrypt-proxy on the device with no other dependencies or software.

At the very least, I'd strongly recommend using Magisk to run and manage dnscrypt. I used to roll my own solution (similar to what you're after & documented here) but switched to Magisk a couple of years ago because Universal Init.d would no longer work with newer versions of Android/LineageOS. At first I was hesitant (why run Magisk if I could just make it work with scripts?). After converting my stuff to a Magisk module and using that to manage, install, and run it, I've never been happier with a solution.

Why? Things got difficult to manage. Like the small problems you've encountered, every OS update or at random seemingly out of nowhere, some issue would pop up and I'd have to mess with or tweak things to get it working again. Sometimes I could go weeks without problem switching between cellular and wifi, then reboot one day and nothing was working. This no longer happens with Magisk and the service always runs properly and is easy to restart or debug (using shell scripts) if needed.

In response to your questions...

  1. Why (even with manual starting of the service) the behavior is different when using WiFi?

I haven't run into anything like this for a while so it's hard to say (what OS and device are you using?) but sometimes I'd seen weird behavior where a root shell resolved names differently than a non-root shell, or blocking didn't appear to work from shell but worked fine in a browser. Watch out for IPv6 only DNS resolvers on some wifi or cellular networks. You probably don't have IPv6 rules working (I don't) and the proxy doesn't work for me when there are no IPv4 DNS resolvers.

  1. How to make this service work on boot with all connections (cellular, WiFi, reverse USB tethering, etc) without requiring manual starting through ADB or additional apps (assuming one already has root and init.d support)?

Heavily going to depend on what OS and platform you're using. See my earlier link about Universal Init.d; that was a pretty minimal way that used to work for starting the proxy. Newer Android versions don't support this and Magisk was the easiest way I found for doing this. There are a few basic Magisk dnscrypt modules, or you could easily make your own in an evening or two and I'd be happy to share my code with you as a starting point as well.

Feel free to DM me with questions or post back.

@emanruse
Copy link
Author

emanruse commented Jan 3, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 3, 2023

Installing dnscrypt-proxy with a flashable zip or manually pushing all files with adb makes no difference when it comes to automatically starting dnscryp-proxy at boot up. You have 3 options without building the ROM.

  1. install dnscrypt files any way you like and launch dnscrypt automatically after boot by using another root application (ie; afwall). This will bypass the need to fix selinux rules. Afwall can run additional scripts as root on boot and is not affected by selinux rules.

  2. install magisk and use magisk to edit selinux rules which is explained in the link a few posts back. Then you can install dnscrypt manually or use dnscrypt magisk module.

  3. install necessary files any way you want and rebuild boot.img with updated sepolicy.

@emanruse
Copy link
Author

emanruse commented Jan 4, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 6, 2023

@emanruse

If you extract the flashable zip file I posted for you, then inside that file is an edify script called "updater-script". That script should tell you what actions need to be taken on each file. Also, inside that zip is a "system" folder which contains the structure of where each file is copied to.

In regards to patching and building the boot.img, I already posted the required changes for the sepolicy a few posts back (for cm-14.1 branch). The exact sepolicy changes will depend on what version of android you are using, but they are basically the same for all versions of Android. Although, building the boot.img is out of scope for this thread. I suggest looking into setting up an android build environment and searching for build documentation for the rom you are using.

@emanruse
Copy link
Author

emanruse commented Jan 6, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 6, 2023

999 is just an undefined AID, which is why the author chose it in his howto. I decided to use a predefined non-privileged user (nobody) instead of an undefined AID. The user "nobody" is commonly used in linux to run daemons as non-privileged processes. Before the dnscrypt-proxy service is started, root executes dnscrypt-cache to make sure dnscrypt-proxy has a cache directory setup with proper permissions set to user nobody. User nobody does not have permission to create it's cache directory on initial setup. Look at https://github.com/syphyr/dnscrypt_proxy_prebuilt/blob/master/dnscrypt_proxy.rc to see how things are started. The android service will start dnscrypt-proxy when "setprop persist.privacy.dnscrypt 1" is executed and stop dnscrypt-proxy when "setprop persist.privacy.dnscrypt 0" is executed.

When using the flashable zip file, you will still need to patch the boot.img. The boot.img contains the sepolicy and the flashable zip does not touch the boot.img. You could just use adb to push the files, set the permissions, chown to proper user/group, and chcon to proper selinux context label (hint: this info is found in the updater-script).

The update-binary is created when building the ROM and often reused to create other flashable zip files. There are lots of tutorials on how to manually sign zip/apk files for android. The zip file is made by basically just compressing a directory with the zip command. Maybe the easiest way for you to start is by using adb and setting it up manually. I suggest to focus on creating a zip file after you get it working.

@emanruse
Copy link
Author

emanruse commented Jan 7, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 8, 2023

  1. Why (even with manual starting of the service) the behavior is different when using WiFi? (asked initially)
    A: I do not have this issue. This depend on your version of android or dnscrypt's iptables script is not setup properly.

  2. Who/What changes props?
    A: The setprop command or options in Settings

  3. Why should anyone turn dnscrypt off?
    A: Irrelevant

  4. Why does your version lack /system/bin/logwrapper?
    A: Its not needed

  5. What is class main, why do you have it and Irfan does not?
    A: https://android.googlesource.com/platform/system/core/+/master/init/README.md

  6. Why does your version lack seclabel u:r:dns_crypt:s0?
    A: Because I set selinux file contexts using sepolicy, not in init.

  7. Why do you not use capabilities NET_BIND_SERVICE and NET_RAW?
    A: Because NET_BIND_SERVICE is only needed when using ports 1-1024. I am using port 5454 for dnscypt-proxy.

  8. Why do you use groups inet, net_raw and net_admin, considering the later two should be capabilities (not groups)?
    A: Because the version of android I'm using does not support setting capabilities in init.

  9. What does oneshot do and why you have it and he doesn't?

  10. What means disabled?
    A: https://android.googlesource.com/platform/system/core/+/master/init/README.md

  11. How can one find out if those really differ on the particular Android version and phone one uses and make the necessary corrections?
    A: Read the sepolicy

  12. What is the way to have universal step 4 (applicable to all Android versions and phones)?
    A: none

  13. Where is the source code of /META-INF/com/google/android/update-binary?
    A: Android recovery

  14. How to build update-binary from source code?
    A: Out of scope for this thread. But don't bother, its irrelevant for getting this working.

  15. What are the pros and cons of using something like https://github.com/doppelhelix/android_update-binary_replacement instead of a compiled update-binary?
    A: Irrelevant

  16. How to sign the zip?

  17. Where does one get the primary key used to sign the zip?

  18. Where is the source code of the zip signing software?

  19. How to build the zip signing software from source code?
    A: Google

  20. Does backuptool.functions exist in every recovery?
    A: No

  21. On Linux I see I have user and group named dnscrypt. How can we do the same on Android?
    A: You don't. Android is not linux.

  22. Please kindly provide actual steps, explaining what each step does, similarly to what Irfan Latif did.
    A: This depends on the structure of your ROM and will require research. All I can say is that take a look at updater-script for hints.

ui_print("**********************************************");
ui_print("              DNSCrypt for ARM64              ");
ui_print("**********************************************");

ui_print("Installing files.");
run_program("/sbin/mount", "/system");
run_program("/sbin/mount", "-o", "remount,rw", "/system", "/system");

package_extract_dir("system", "/system");

ui_print("Setting metadata.");
set_metadata_recursive("/system/addon.d", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0755, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/etc/dnscrypt-proxy", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0644, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata("/system/bin/dnscrypt", "uid", 0, "gid", 2000, "mode", 0755, "capabilities", 0x0, "selabel", "u:object_r:dnscrypt_proxy_exec:s0");
set_metadata("/system/bin/dnscrypt-iptables", "uid", 0, "gid", 2000, "mode", 0755, "capabilities", 0x0, "selabel", "u:object_r:dnscrypt_proxy_exec:s0");
set_metadata("/system/etc/init/dnscrypt_proxy.rc", "uid", 0, "gid", 0, "mode", 0644, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata("/system/xbin/dnscrypt-proxy", "uid", 0, "gid", 2000, "mode", 0755, "capabilities", 0x0, "selabel", "u:object_r:dnscrypt_proxy_exec:s0");

run_program("/sbin/umount", "/system");
ui_print("Done.");

@jedisct1 jedisct1 changed the title Documenatation about installing on Android Documentation about installing on Android Jan 8, 2023
@emanruse
Copy link
Author

emanruse commented Jan 8, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 9, 2023

  1. Why should anyone turn dnscrypt off?

For the same reasons linux users want to be able to start and stop services. Perhaps for testing reasons, perhaps to update a config without having to reboot.

108a. How can I check which of the two is supported by Replicant?
Check system/core/init for functions that support the options you want to use. Need to setup a build environment for the ROM to do this.

111a. Where/How?
In system/sepolicy, which requires setting up build environment for your ROM.

  1. Where is the source code of /META-INF/com/google/android/update-binary?
    Android recovery is a github repo. For example, TWRP is found here: https://github.com/omnirom/android_bootable_recovery

107-120:
https://developer.android.com/studio/publish/app-signing

  1. Please kindly provide actual steps

I'll provide you the steps for one of the files in updater-script and you should be able to repeat the process for the rest of the files.

(Reboot to recovery first)
adb shell
mount /system
exit
adb push dnscrypt /system/bin/
adb shell
cd /system/bin
chmod 755 dnscrypt
chown 0:2000 dnscrypt
chcon u:object_r:dnscrypt_proxy_exec:s0 dnscrypt

Note that if you are using my github repo, dnscrypt-cache is not added to updater-script example I posted, but dnscrypt-cache is the exact same procedure for /system/bin/dnscrypt above. Also, the chcon label (u:object_r:dnscrypt_proxy_exec:s0) I used in the example above is found in the selinux changes I posted to create a selinux domain for dnscrypt.

@emanruse
Copy link
Author

emanruse commented Jan 9, 2023 via email

@emanruse
Copy link
Author

emanruse commented Jan 10, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 10, 2023

@emanruse

I noticed that your iptables script does not include TCP, which is incorrect and will definitely cause problems with forwarding dns requests. I suggest you look closer at my repo since I fixed several bugs with iptables.

I also suggest you start with setting up an android build environment and learn how to build the boot.img. You do not have to build the entire ROM. Building only the boot.img is much faster and will solve your selinux issues. Just patch the sepolicy rules and build the boot.img. I do not know anything about using sepolicy-inject, manually repacking the boot.img, or using Magisk to edit the sepolicy.

@emanruse
Copy link
Author

emanruse commented Jan 11, 2023 via email

@GNUtoo
Copy link

GNUtoo commented Jan 15, 2023

Hi,

Sorry for the delay (Some questions were also asked on
the Replicant mailing list long time ago but I've a huge mail
backlog, so I'm really late here).

I don't have a big expertise in running services like that at boot across a wide variety of Android distribution, though I can respond to some of the Replicant 6.0 specific questions.

For SELinux logs, they might be in kernel log (you can get it with 'dmesg' as root), though I didn't check for real as I don't have an easy way to trigger a violation.

That [rebuilding the boot.img] is a big concern to me. Again,
as explained in my initial post, I researched into that and
the process of unpacking and repacking the boot.img with no
modification whatsoever
always results in a smaller image
file.

During my research, I have read stories about people
uploading such "unmodified, just repacked" image back to their
device resulting in a boot loop. I don't know if this will
happen with my device.

What is worse - I don't know how to restore the previous
working state of the device if this happens.

This is relatively easy to do:
(1) you need to understand which Replicant version/images you are
running and download the corresponding zip file. The Replicant wiki
has an article about that if you don't remember the version.
(2) The boot.img is inside the zip file.
(3) You can restore the original boot.img with this command
(this command is specific to the GT-I9300):
heimdall flash --BOOT boot.img

  1. How to sign the zip?
  2. Where does one get the primary key used to sign the zip?
  3. Where is the source code of the zip signing software?
  4. How to build the zip signing software from source code?

Basically when building a Replicant 6.0 image, various keys are generated automatically during the build with a script.

You still need to manually enter some data during the first build though if my memory is correct.

One of the generated keys is used to sign the zip. And the ZIPs then checked by the recovery. For instance this enables to reduce the complexity of the installation instruction at the expense of a small increase of security risk.

I can't give you access to the keys as they give the ability to make official Replicant images.

However if you build your own recovery image from the Replicant source code, it will also generate keys that you may be able to reuse to sign zips in the same way that the release zips are signed.

Another option would be to somehow add support in Replicant 6.0 for generating recoveries that don't check signatures, or write some program that somehow disable the signature check of an existing recovery.

I'd need to check (again) how the recovery check the signatures, but if there is an easy way to disable that, a way to go would be to write a script that takes in input a recovery image and produce a modified image without the signature checks.

We already have a program that can add an adb root shell without authentication to the recovery.img or boot.img, for debugging purposes, though it has a big hack: we use sed to change a (boot) property value not to have to unpack and repack the initramfs.

  1. Why should anyone turn dnscrypt off?
    This way an Android distribution could ship dnscrypt for everyone, and decide in a good default (like have it off or on by default) but also enable people to make the opposite choice (like enable it if it's off).

What do you mean? "Android recovery" is a mode of booting the
phone. Please be clearer.
It's in the Replicant recovery.img image, so the source code is in Replicant somewhere.

One of the issue is that this source code is huge, so it often takes time to find stuff.

FWIW, today I tried mkbootimg and unpackbootimg by osm0sis:

https://github.com/osm0sis/mkbootimg

So far, it seems to be the only version which can be easily built
from source (in seconds) and most importantly - unpacking and
repacking the image results in identical file. The other
versions (including the newer Python ones) of these image tools I
tried create a repacked image which differs from the original. If
you know a better tool, please share.
Some GNU/Linux distriubtions also packages some of these tools. Parabola and Guix have mkbootimg, and they also have abootimg.

Denis.

@GNUtoo
Copy link

GNUtoo commented Jan 15, 2023

Apparently I need a space after the quotes, otherwise it takes the next line in the quote. Because of that some of my answers ended up in the quote.

@emanruse
Copy link
Author

emanruse commented Jan 15, 2023 via email

@emanruse
Copy link
Author

emanruse commented Jan 18, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 18, 2023

@emanruse

I've never built Replicant, but most likely the toolchain is prebuilt when you setup the android build environment. I've never had to build the toolchain when compiling a ROM.

Use the recommended version of Linux when setting up your Android build environment. If you try to use a new version of Linux, there will most likely be conflicts and problems.

Building the boot.img is as simple as "mka bootimage" when building AOSP. I am unfamiliar with Replicant sources but I would assume it is very similar to AOSP.

Perhaps there is a help channel for Replicant development that can assist you with the details of building their ROM.

@emanruse
Copy link
Author

emanruse commented Jan 19, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 19, 2023

@emanruse

As you have already mentioned, there are tools to manually unpack/repack the boot.img, but I do not have any knowledge of changing the sepolicy without building the boot.img from source. Perhaps there is something on XDA that would help?

As for creating the rules on the .te file, this is done by reading the selinux denial errors in dmesg and fixing each error until they are gone. Tools like audit2allow can be useful for translating the selinux errors from dmesg. This is a good guide for fixing selinux denials: https://source.android.com/docs/security/features/selinux/validate

@emanruse
Copy link
Author

emanruse commented Jan 20, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Jan 20, 2023

@emanruse

I used Google's official documentation on how to setup an android build environment. Google uses Ubuntu. The cm-14.1 branch (LineageOS) that I am using recommends Ubuntu 18.04 Bionic. You will have to see if your device is supported by LineageOS, perhaps only on an older branch.

Are you saying that what you did was:

Correct.

@emanruse
Copy link
Author

emanruse commented Apr 26, 2023 via email

@syphyr
Copy link
Contributor

syphyr commented Apr 27, 2023

Could you advise on the specific steps which are necessary to modify the sepolicy for the purpose of running the dnscrypt-proxy service? Which files do I have to modify and how before rebuilding?

I'm not familiar with Replicant OS, but the changes to selinux that I gave is for Android 7 (Nougat). It should not be too difficult to use the selinux changes I posted as an example and port them to your specific OS.

@1alexman1
Copy link

Why dnscrypt cannot be found in Fdroid? Are you intend to do it?Thx

@karolyi
Copy link

karolyi commented Jan 10, 2024

FWIW: #2328 (comment)

@emanruse
Copy link
Author

emanruse commented Jan 12, 2024 via email

@karolyi
Copy link

karolyi commented Jan 12, 2024

You can install it from F-Droid which means it's open source and can be maintained even after its current maintainer stops.

But in the end, it's up to you.

@elovin
Copy link

elovin commented Feb 20, 2024

I use the arm64 build with lineageOS 20 (Android 13) at the moment.

Although I run the service as root on system start without SELINUX which is fine for me since I do not do online banking on my phone.

In case it helps someone here is the link to the repo:
https://github.com/elovin/lineageos-clean-browsing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants