It is necesarry to update in dev branch docker-compose for https scenario.
Good sample is provided from @bravecobra -
https://github.com/bravecobra/identityserver-ui
I would like to use http://127.0.0.1.xip.io - with https for development scenario as well - but currently it does not work properly on my machine - I need spend more time on this.
Currently this feature is blocker for next release, because I would like to provide support for docker as well and https is required.
Any help/PR is really welcome. 馃憤 馃殌
Thanks
Why would you want to run https. I think a reverse proxy like ngix should be in front of the UI that will be using https
I think would be good if you make the feature configurable. I want to run the ui inside a kubernetes cluster using http and outside the kubernetes cluster to be access via https
This is exactly what I want to achieve - configure ngnix for https scenario, ideally with xip.io, without modification host table. 馃槈 Your scenario will be definetely supported. Thanks for feedback.
Yes. I have done that. I currently use that setup for my local development. I have not use https for local development because I don't have such requirement but I suppose you can use a self-sign cert.
I am using traefik as a reverse proxy. https://docs.traefik.io/https/tls/ I have not used a self-sign cert. Below is my docker-compose
This way I don't have to be editing the host file. I currently use traefik.me which is similar to xip.io
```version: '3.7'
services:
traefik:
image: "traefik:2.2.0"
container_name: "traefik"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.traefik.address=:9090"
ports:
- 80:80
- 9090:9090
restart: unless-stopped
environment:
- AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
- AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
- AZURE_RESOURCE_GROUP=${AZURE_RESOURCE_GROUP}
- AZURE_SUBSCRIPTION_ID=${AZURE_SUBSCRIPTION_ID}
- AZURE_TENANT_ID=${AZURE_TENANT_ID}
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
skoruba.identityserver4.admin:
image: skoruba-identityserver4-admin
container_name: IdentityServer4Admin
labels:
- "traefik.enable=true"
- "traefik.http.routers.identityserver4Admin.rule=Host(idsrv4admin.traefik.me)"
- "traefik.http.routers.identityserver4Admin.entrypoints=web"
command: dotnet Skoruba.IdentityServer4.Admin.dll /seed
environment:
- "ConnectionStrings__ConfigurationDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__PersistedGrantDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__IdentityDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__AdminLogDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__AdminAuditLogDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__DataProtectionDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "AdminConfiguration__IdentityAdminBaseUrl=http://idsrv4admin.traefik.me"
- "AdminConfiguration__IdentityAdminRedirectUri=http://idsrv4admin.traefik.me/signin-oidc"
- "AdminConfiguration__IdentityServerBaseUrl=http://login.traefik.me"
- "AdminConfiguration__RequireHttpsMetadata=false"
- "AdminConfiguration__PageTitle=SchoolGrades IdentityServer4 Admin"
volumes:
- "./shared/serilog.json:/app/serilog.json"
- "./shared/identitydata.json:/app/identitydata.json"
- "./shared/identityserverdata.json:/app/identityserverdata.json"
skoruba.identityserver4.sts.identity:
image: skoruba-identityserver4-sts-identity
container_name: IdentityServer4
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.identityserver4STS.rule=Host(login.traefik.me)"
- "traefik.http.routers.identityserver4STS.entrypoints=web"
environment:
- "ConnectionStrings__ConfigurationDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__PersistedGrantDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__IdentityDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__AdminLogDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__AdminAuditLogDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- "ConnectionStrings__DataProtectionDbConnection=Server=${SQL_HOST};Database=IdentityServer4Admin;User Id=${SQL_HOST_USER};Password=${SQL_HOST_PWD};MultipleActiveResultSets=true"
- AdminConfiguration__PageTitle=SchoolGrades IdentityServer4
- RegisterConfiguration__Enabled=False
volumes:
- "./shared/serilog.json:/app/serilog.json"
networks:
default:
aliases:
- login.traefik.me```
Traefik will indeed solve the reverse proxy problem the same way nginx does. Just a different implementation.
The TLS support is a issue for which you will need a certificate somehow, either a really one like Let'sEncrypt or a self-signed one. I think the idea is to be able to verify the TLS support on a dev environment, nothing more. Which kind of cert you use is less relevant I guess. In my repo I tried to be as close to a production environment as possible and still offer a fully working solution exposing the difficulties of getting it to work.
xip.io will not solve the reverse dns fully. It's a shortcut, but you'll hit it quickly once you start with reverse proxies.
agreed. i have not tried using the self-signed cert. I am almost sure it will work and I will have https. My point is that the https should be the responsibility of nginx or traefik, not of the skoruba sts.
suppose i want to use Azure Application Gateway infront of skoruba sts
i stand to be correct. i am not a networking person
True, in my solution the cert is part of nginx, not the sts.
I think something along these lines could help and be a good start. Here's the explanation of each container:
services:
nginx-proxy:
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- /etc/nginx/certs
- /etc/nginx/vhost.d
- /usr/share/nginx/html
- "/var/run/docker.sock:/tmp/docker.sock:ro"
image: jwilder/nginx-proxy
letsencrypt-nginx-proxy-companion:
container_name: nginx-proxy-letsencrypt
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
environment:
- DEFAULT_EMAIL=PUTYOUREMAILHERE
image: jrcs/letsencrypt-nginx-proxy-companion
nginx:
container_name: nginx
environment:
- VIRTUAL_HOST=127.0.0.1.xip.io
- LETSENCRYPT_HOST=127.0.0.1.xip.io
image: nginx
This part is not directly related to https but it is related to nginx (some might've experienced it) as it might cause 502 bad gateway when authorizing a client. It is due the fact that nginx doesn't allow a large header content. To fix that nginx.conf needs to be modified and inlcude
http{
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
large_client_header_buffers 4 16k;
}
@vpetkovic - thanks for your suggestion and sample configuration, I will definitely test it. 馃憤馃徏
Unfortunatelly I got this error:
There were too many requests of a given type :: Error creating new order :: too many certificates already issued for: xip.io: see https://letsencrypt.org/docs/rate-limits/
I am sorry I wasn't aware of such limitation when using xip.io with letsencrypt specifically, I used it with my own domain before to avoid dealing with self-signed certs and annoyances that come with it when trying to setup local environment for SSL as well as to have dev resemble prod env as close as possible.
So, it might still be a viable option for POC and pre-release scenarios if you own the domain.
I have not tested below (maybe i can do that over the weekend) but If to use self-signed certs instead of letsencrypt it could be as easy as getting rid of letsencrypt container then run the following to create self-signed certs using openSSL :
cd /etc/nginx/certs
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/certs/cert.key -out /etc/nginx/certs/cert.crt
Then modify default.conf in nginx container to point to self-signed certs created above.
server {
listen 80;
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/certs/cert.crt;
ssl_certificate_key /etc/nginx/certs/cert.key;
}
Maybe additionally force http traffic to https:
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/certs/cert.crt;
ssl_certificate_key /etc/nginx/certs/cert.key;
}
Not sure yet if any additional SSL config inside of default.conf is necessary.
That's why I used mkcert in my example to generate self signed certificates easily on any OS. The end-result is basically the same thing. Using Let's Encrypt will only work if either your endpoint is internet accessible on port 80 (which for most isn't the case) or the DNS resolves the challenge Let's Encrypt requires. If neither of those is available, Let's Encrypt won't work and you will need to resort to self-signed certificates. For dev purposes the latter is more than sufficient for testing.
I think this setup's attempt is to provide a solution that works for everybody in any given environment, thus I'd choose for self-signed ones as that works for everybody regardless of the environment. Making those certs should there for be easy, something that mkcert offers.
Of course you don't want to deploy that exact same solution with self-signed certificates to production. There you will need to use a real certificate or complete the Let's Encrypt setup.
This part is not directly related to https but it is related to nginx (some might've experienced it) as it might cause 502 bad gateway when authorizing a client. It is due the fact that nginx doesn't allow a large header content. To fix that nginx.conf needs to be modified and inlcude
http{ proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; large_client_header_buffers 4 16k; }
I increased the buffer in my setup as well.
Sorry @skoruba , I haven't had a chance to look at this issue nor play around with self-signed certs as I originally imagined I would, but as you @bravecobra pointed out mkcert might be clean and easy way of dealing with it.
I have never used mkcert before and will be definitely add this to my arsenal as well, and hopefully this weekend will have a chance to spin those containers up and come up with a setup, now that I finally got all the parts for my new rig after a week without one lol
I'm glad you guys seem to have a path for this. My local setup (Windows 10) uses https://github.com/nginx-proxy/nginx-proxy and all of my microservices are behind it: 4 "public" web sites, 1 IdentityServer4, 1 Skoruba IdentityServer.Admin, 1 gateway, and about 10 private services.
I wrote a .ps1 to do a lot of prep work to help with the setup. Things like download OpenSSL to generate a cert to save in the Windows Certificate Store and that same cert is used in the docker images, modify the etc/hosts file so I can setup https://acme.mydomain.local and https://identityserver.admin.mydomain.local, etc.
I was also able to split the project out into 3 docker-compose files (working toward 4 or 5).
There may have been easier ways of doing this... and it took a good couple weeks of me learning/implementing, but it seems to have made development easier for my team.
@DaleyKD - can you share your setup please? Thanks
@DaleyKD yeah, based on your description, I think my configuration is a bit easier, but with the same end result.
Done - PR #657. Thanks for your help/suggestions.