How to properly setup my Ionic (Angular) dev machine with self-signed certificate?

时光怂恿深爱的人放手 提交于 2021-01-29 14:49:32

问题


I'm working on a Ionic-Angular app and faced quite a few issues due to clear text traffic. So I decided to switch to https even while coding but it wasn't so easy.

I open this question and propose the answer I found to keep a trace and hopefully save you some time if you would like to do the same.


回答1:


Prerequisite

You need a hostname for your dev machine. This name will be declared in certificates and https services will be accessed using this hostname (URLs have to be like https://[hostname]:... for certificate check to pass).

If your network doesn't have a DNS already, you might use something like MaraDNS hosted on your dev-machine (see P.S. for sample configuration).

Generate certificate (and signing key) in various formats

self_signed_template.config:

[req]
default_bits       = 2048
default_md         = sha256
prompt             = no
default_keyfile    = [hostname]_self_signed_key.pem
encrypt_key        = no

distinguished_name = dn

req_extensions     = v3_req
x509_extensions    = v3_req

[dn]
C            = PF
ST           = Tahiti
L            = Papeete
O            = Tahiti-Devops
emailAddress = foo@bar.pf
CN           = [hostname]

[v3_req]
subjectAltName   = critical, @alt_names
basicConstraints = critical, CA:false
keyUsage         = critical, keyCertSign, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = critical, serverAuth, clientAuth

[alt_names]
DNS.1 = [hostname]
DNS.2 = localhost
DNS.3 = 10.0.2.2

self_signed.sh

#!/bin/bash

rm -f ${1}_self_signed.config;
sed 's/\[hostname\]/'$1'/g' self_signed_template.config > ${1}_self_signed.config
openssl req -config ${1}_self_signed.config -new -out ${1}_self_signed_cert.pem
openssl x509 -req -days 365 -extfile ${1}_self_signed.config -extensions v3_req -in ${1}_self_signed_cert.pem -signkey ${1}_self_signed_key.pem -out ${1}_self_signed.crt
openssl pkcs12 -export -out ${1}_self_signed.pfx -inkey ${1}_self_signed_key.pem -in ${1}_self_signed.crt -name ${1}_self_signed -password pass:$3
keytool -importkeystore -destkeystore ${1}_self_signed.jks -deststorepass $4 -srckeystore ${1}_self_signed.pfx -srcstorepass $4 -srcstoretype pkcs12 -alias ${1}_self_signed
keytool -importkeystore -destkeystore "$2/lib/security/cacerts" -deststorepass changeit -srckeystore ${1}_self_signed.pfx -srcstorepass $4 -srcstoretype pkcs12 -alias ${1}_self_signed

Then run something like ./self_signed.sh laptop-jerem "/c/Program Files/Java/jdk-11.0.8" secret changeit. Arguments are:

  1. hostname
  2. JAVA_HOME
  3. key password
  4. keystores password

Admin privileges is required to import the certificate in Java's cacert.

On windows, Git Bash has all of sed, openssl and keytool on the path.

Import this certificate as trusted root authority

If you add this certificate to trusted root authorities, your browser will display no error nor warning when navigating URLs like https://[hostname]:....

On windows, this can be done with certmgr.msc (right click trusted root authorities and then import). Please comment if you successfully do the same on other OS.

Configure Ionic-Angular to serve over https with this certificate

Edit angular.json to set "sslCert" and "sslKey" under your-project/architect/serve/options/ and point it to respectively [hostname]_self_signed.crt and [hostname]_self_signed_key.pem generated earlier.

This is enough for the right certificate to be picked when running ionic serve --ssl --host=[hostname] or ionic capacitor run android -l --ssl --host=[hostname]

Embed certificate in Android project

Reminder: android resource folder is android/app/src/main/res/ under your project or app/res/ in Android Studio

First, copy [hostname]_self_signed.crt to raw resources, replacing -, if any, with _ in hostname.

Create network_security_config.xml in xml resources (careful with modified hostname)

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
          <certificates src="@raw/[hostname]_self_signed"/>
          <certificates src="system"/>
        </trust-anchors>
    </base-config>
</network-security-config>

important note: if all your trafic is served over https, you should set cleartextTrafficPermitted to false (which is default value since Android 9). Consider doing so for prod build at least.

Finally, edit AndroidManifest.xml and add android:networkSecurityConfig="@xml/network_security_config" to your <application > tag

Embed certificate in iOS project

I have no experience with iOS, please feel free to comment or add an answer if you get it working.

Configure your backends to serve over https with self-signed certificate

Well... it really depends on the stack you use. A few samples:

  • For Kestrel (.Net app debugged in Visual Studio), set ASPNETCORE_Kestrel__Certificates__Default__Password and ASPNETCORE_Kestrel__Certificates__Default__Path, the second pointing to the [hostname]_self_signed.pfx
  • For spring-boot, copy [hostname]_self_signed.jks into src/main/resources/ and set server.ssl properties
  • Keycloak has comprensive doc to setup the server with custom certificate
  • Please comment if you get other backend types working

P.S. The dwood3rc.txt file I use for MaraDNS:

upstream_servers={}
# This are my internet provider DNS servers
upstream_servers["."]="104.42.155.203,52.229.31.10,113.197.68.2,113.197.68.3"

# My dev machine IP on local network
bind_address="192.168.8.100"

# The IPs allowed to connect (smartphones I test from)
recursive_acl="192.168.8.0/24"

# This is the file Deadwood uses to read the cache to and from disk
cache_file = "dw_cache_bin"

# laptop-jerem is referenced as [hostname] all over the tutorial
ip4={}
ip4["laptop-jerem."]="192.168.8.100"

Once the DNS server is up (net start deadwood) on my dev machine, I configure clients to use it as primary DNS (edit wifi network properties which does not require rooted device) et voilà!

P.S.2 Keycloak standalone configuration allowing test devices to connect to OpenId endpoints over https

Copy [hostname]_self_signed.jks to standalone/configuration/.

Edit standalone/configuration/standalone.xml to replace ${jboss.bind.address:127.0.0.1} with ${jboss.bind.address:0.0.0.0}. Save and close.

Start Keycloak with bin/standalone[.bat|.sh], then using bin/jboss-cli[.bat|.sh]:

connect
/subsystem=keycloak-server/spi=hostname/provider=default:write-attribute(name=properties.frontendUrl,value="https://[hostname]:8443/auth")
/core-service=management/security-realm=UndertowRealm:add()
/core-service=management/security-realm=UndertowRealm/server-identity=ssl:add(keystore-path=[hostname]_self_signed.jks, keystore-relative-to=jboss.server.config.dir, keystore-password=[keystore_password])
/subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=security-realm, value=UndertowRealm)
reload


来源:https://stackoverflow.com/questions/63874373/how-to-properly-setup-my-ionic-angular-dev-machine-with-self-signed-certificat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!