How can I use Route 53 as the DNS Challenge for Lets Encrypt in Traefik? - amazon-route53

My local domain is home.turtlesystems.co.uk. I am using Traefik on a local Docker Swarm cluster within this domain.
As there is no direct Internet access to the cluster I cannot use the HTTPS challenge for Lets Encrypt so I am attempting to use Route53 as the DNS provider.
I have set up a Zone in Route53 for my home domain, which is a sub domain of turtlesystems.co.uk which I own.
My traefik.toml file looks like:
debug = true
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
# Enable ACME (Let's Encrypt) automate SSL
[acme]
email = "xxxxxxxxxxxxxxxxxxxx"
storage = "/etc/traefik/acme.json"
dnsProvider = "route53"
entryPoint = "https"
onDemand = true
onHostRule = true
acmeLogging = true
[[acme.domains]]
main = "home.turtlesystems.co.uk"
# Allow access to the Web UI
[web]
address = ":8080"
# Configure how docker will be run
[docker]
endpoint = "unix://var/run/docker.sock"
domain = "traefik"
watch = true
exposedbydefault = false
swarmmode = true
I have created a service for Portainer that has the following Traefik labels:
traefik.port=9000
traefik.docker.network=traefik-net
traefik.frontend.rule=Host:turtle-host-03.home.turtlesystems.co.uk;PathStripPrefix:/portainer
traefik.backend=portainer
traefik.enable=true
traefik.backend.loadbalancer=wrr
As I have acmeLogging enabled in the traefik.toml file I was hoping to get some more information about what is happening or not happening, but I only get the following INFO logs:
reverse_proxy.1.rqebssg613a8#turtle-host-03 | legolog: 2017/12/15 13:16:32 [INFO][home.turtlesystems.co.uk] AuthURL: https://acme-v01.api.letsencrypt.org/acme/authz/z52B_D2iHeITPqT_7K-Z-Y-ieir3VT4l1qGW6tShrd8
reverse_proxy.1.rqebssg613a8#turtle-host-03 | legolog: 2017/12/15 13:16:32 [INFO][turtle-host-03.home.turtlesystems.co.uk] AuthURL: https://acme-v01.api.letsencrypt.org/acme/authz/OxWRpDR3KZm4E0nGngVSRZgF3iE2nhQ3jlNaWtxbd08
reverse_proxy.1.rqebssg613a8#turtle-host-03 | legolog: 2017/12/15 13:16:32 [INFO][home.turtlesystems.co.uk] acme: Could not find solver for: tls-sni-01
reverse_proxy.1.rqebssg613a8#turtle-host-03 | legolog: 2017/12/15 13:16:32 [INFO][home.turtlesystems.co.uk] acme: Trying to solve DNS-01
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:06Z" level=debug msg="Look for provided certificate to validate [turtle-host-03.home.turtlesystems.co.uk]..."
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:06Z" level=debug msg="Look for provided certificate to validate [turtle-host-03.home.turtlesystems.co.uk]..."
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:06Z" level=debug msg="No provided certificate found for domains [turtle-host-03.home.turtlesystems.co.uk], get ACME certificate."
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:06Z" level=debug msg="Challenge GetCertificate turtle-host-03.home.turtlesystems.co.uk"
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:06Z" level=debug msg="No provided certificate found for domains [turtle-host-03.home.turtlesystems.co.uk], get ACME certificate."
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:06Z" level=debug msg="Challenge GetCertificate turtle-host-03.home.turtlesystems.co.uk"
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:07Z" level=debug msg="Look for provided certificate to validate [turtle-host-03.home.turtlesystems.co.uk]..."
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:07Z" level=debug msg="No provided certificate found for domains [turtle-host-03.home.turtlesystems.co.uk], get ACME certificate."
reverse_proxy.1.rqebssg613a8#turtle-host-03 | time="2017-12-15T13:17:07Z" level=debug msg="Challenge GetCertificate turtle-host-03.home.turtlesystems.co.uk"
reverse_proxy.1.rqebssg613a8#turtle-host-03 | legolog: 2017/12/15 13:17:10 [INFO][home.turtlesystems.co.uk] Checking DNS record propagation using [127.0.0.11:53]
As can be seen it is trying to use a DNS challenge, but I am not getting a certificate.
When I first set all this up it did all work, in fact I wrote a blog about it, but now it does not. When I look at my AWS account I can see that the AWS_ACCESS_KEY I have created for this purpose is being used, but nothing seems to be entered into the Zone.
I am passing AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY and AWS_REGION into the Portainer service as environment variables.
Is there more logging I can turn on? Is there anyway to see logs in AWS for Route 53?
Update
After playing around with this I noticed that Traefik is trying to use 127.0.0.11:53 as the DNS server on which to try and check that the TXT record has been created.
I then added --dns and --dns-search to the Traefik service but this did not have any effect on the address that Trafik uses for DNS. Is there another option I can set in Traefik to force this?

Go to AWS, Create AIM custom policy
Paste the following JSON as the policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:GetChange",
"route53:GetChangeDetails",
"route53:ListHostedZones"
],
"Resource": [
"*"
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:SetLoadBalancerListenerSSLCertificate"
],
"Resource": [
"*"
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"iam:ListServerCertificates",
"iam:GetServerCertificate",
"iam:UploadServerCertificate"
],
"Resource": [
"*"
]
}
]
}
name the policy "dnsChallenge" (or whatever you like)
Create new AIM user and attach above policy
Copy the new user's keys as you'll need to set them as environment variables
Go to AWS Route53 and look at the hosted zone.
You'll want 2 A records -- for yourdomain.com and *.yourdomain.com both pointing to the static IP of the host running traefik.
Copy down the Hosted zone ID for the domain you are wildcarding.
Define the following environment variables and make sure they are available when traefik starts.
export AWS_ACCESS_KEY_ID=*****************
export AWS_SECRET_ACCESS_KEY=**********************************
export AWS_HOSTED_ZONE_ID=*************
edit traefik.toml
[acme] # Automatically add Let's Encrypt Certificate.
email = "youremail#gmail.com"
storage= "acme.json" # Change to fully qualified and exposed path for docker
entryPoint = "https"
OnHostRule = false
acmelogging = true
# caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
caServer = "https://acme-v02.api.letsencrypt.org/directory"
[acme.dnsChallenge]
provider = "route53"
delayBeforeCheck = 0
[[acme.domains]]
main = "*.yourdomain.com"
sans = ["yourdomain.com"]
From there its a good idea to run it from the command line and watch for the messages..

Adding on bhlowe's answer, I would use a more restricted IAM profile:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:GetChange",
"route53:ListHostedZonesByName"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/<INSERT_YOUR_HOSTED_ZONE_ID_HERE>"
]
}
]
}

Related

Autounseal Vault with GCP KMS

I would like to use auto unseal vault mechanism using the GCP KMS.
I have been following this tutorial (section: 'Google KMS Auto Unseal') and applying the official hashicorp helm chart with the following values:
global:
enabled: true
server:
logLevel: "debug"
injector:
logLevel: "debug"
extraEnvironmentVars:
GOOGLE_REGION: global
GOOGLE_PROJECT: ESGI-projects
GOOGLE_APPLICATION_CREDENTIALS: /vault/userconfig/kms-creds/credentials.json
extraVolumes:
- type: 'secret'
name: 'kms-creds'
ha:
enabled: true
replicas: 3
raft:
enabled: true
config: |
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
seal "gcpckms" {
project = "ESGI-projects"
region = "global"
key_ring = "gitter"
crypto_key = "vault-helm-unseal-key"
}
storage "raft" {
path = "/vault/data"
}
I have created a kms-creds with the json credentials for a service account (I have tried with Cloud KMS Service Agent and owner role but none of them work.
Here are the keys in my key ring :
My cluster is just a local cluster created with kind.
On the first replica of the vault server all seems ok (but not running though):
And on the two others got the normal message claiming that the vault is sealed:
Any idea what could be wrong? Should I create one key for each replica?
OK well, I have succeeded in setting in place the Vault with auto unseal !
What I did:
Change the project (the id was required, not the name)
I disabled the raft (raft.enabled: false)
I moved the backend to google cloud storage adding to the config:
storage "gcs" {
bucket = "gitter-secrets"
ha_enabled = "true"
}
ha_enabled=true was compulsory (with regional bucket)
My final helm values is:
global:
enabled: true
server:
logLevel: "debug"
injector:
logLevel: "debug"
extraEnvironmentVars:
GOOGLE_REGION: global
GOOGLE_PROJECT: esgi-projects-354109
GOOGLE_APPLICATION_CREDENTIALS: /vault/userconfig/kms-creds/credentials.json
extraVolumes:
- type: 'secret'
name: 'kms-creds'
ha:
enabled: true
replicas: 3
raft:
enabled: false
config: |
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
seal "gcpckms" {
project = "esgi-projects-354109"
region = "global"
key_ring = "gitter"
crypto_key = "vault-helm-unseal-key"
}
storage "gcs" {
bucket = "gitter-secrets"
ha_enabled = "true"
}
Using a service account with permissions:
Cloud KMS CryptoKey Encrypter/Decrypter
Storage Object Admin Permission on gitter-secrets only
I had an issue at first, the vault-0 needed to run a vault operator init. After trying several things (post install hooks among others) and comming back to the initial state the pod were unsealing normally without running anything.

Vault transit engine auto unseal does not pass VAULT_TOKEN when starting up?

VAULT-1 Unseal provider:
cat /etc/vault.d/vault.json
"listener": [{
"tcp": {
"address": "0.0.0.0:8200",
"tls_disable" : 1
}
}],
"storage" :{
"file" : {
"path" : "/opt/vault/data"
}
},
"max_lease_ttl": "1h",
"default_lease_ttl": "1h"
}
VAULT-2 Unseal client, this is the vault attempting to auto unseal itself:
cat /etc/vault.d/vault.hcl
disable_mlock = true
ui=true
storage "file" {
path = "/vault-2/data"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = "true"
}
seal "transit" {
address = "http://192.168.100.100:8200"
disable_renewal = "false"
key_name = "autounseal"
mount_path = "transit/"
tls_skip_verify = "true"
}
Token seems valid on VAULT-1:
vault token lookup s.XazV
Key Value
--- -----
accessor eCH1R3G
creation_time 1637091280
creation_ttl 10h
display_name token
entity_id n/a
expire_time 2021-11-17T00:34:40.837284665-05:00
explicit_max_ttl 0s
id s.XazV
issue_time 2021-11-16T14:34:40.837289691-05:00
meta <nil>
num_uses 0
on VAULT-2, I have an env var set:
export VAULT_TOKEN="s.XazV"
I have the policy enabled accordingly on VAULT-1. However when starting the service on VAULT-2:
vault2 vault[758]: URL: PUT http://192.168.100.100:8200/v1/transit/encrypt/autounseal
vault2 vault[758]: Code: 400. Errors:
vault2 vault[758]: * missing client token
Thank you.
If you're starting up the Vault service with systemctl, you may need to configure the service file to include the token in an Environment configuration rather than with export.
https://askubuntu.com/questions/940679/pass-environment-variables-to-services-started-with-systemctl#940797

Error core: failed to lookup token: error=failed to read entry, dial tcp [::1]:8500: getsockopt: connection refused in Vault log

We are performing load test on our application using Jmeter, our application uses consul and vault as a backend service for reading/storing application configuration related data. While performing load testing, our application queries the vault for authentication data and this happens for each incoming request. Initially it runs fine for some duration (10 to 15 minutes) and I can see the success response in Jmete, but eventually after sometime the responses starts failing for all the requests. I see the following error in the vault log for each request but do not see any error/exception in the consul log.
Error in Vault log
[ERROR] core: failed to lookup token: error=failed to read entry: Get http://localhost:8500/v1/kv//vault/sys/token/id/87f7b82131cb8fa1ef71aa52579f155d4cf9f095: dial tcp [::1]:8500: getsockopt: connection refused
As of now the load is 100 request (users) in each 10 milliseconds with a ramp-up period of 60 seconds. And this executes over a loop. What could be the cause of this error? Is it due to the limited connection to port 8500
Below is my vault and consul configuration
Vault
backend "consul" {
address = "localhost:8500"
path = "app/vault/"
}
listener "tcp" {
address = "10.88.97.216:8200"
cluster_address = "10.88.97.216:8201"
tls_disable = 0
tls_min_version = "tls12"
tls_cert_file = "/var/certs/vault.crt"
tls_key_file = "/var/certs/vault.key"
}
Consul
{
"data_dir": "/var/consul",
"log_level": "info",
"server": true,
"leave_on_terminate": true,
"ui": true,
"client_addr": "127.0.0.1",
"ports": {
"dns": 53,
"serf_lan": 8301,
"serf_wan" : 8302
},
"disable_update_check": true,
"enable_script_checks": true,
"disable_remote_exec": false,
"domain": "primehome",
"limits": {
"http_max_conns_per_client": 1000,
"rpc_max_conns_per_client": 1000
},
"service": {
"name": "nginx-consul-https",
"port": 443,
"checks": [{
"http": "https://localhost/nginx_status",
"tls_skip_verify": true,
"interval": "10s",
"timeout": "5s",
"status": "passing"
}]
}
}
I have also configured the http_max_conns_per_client & rpc_max_conns_per_client, thinking that it might be due to the limited connection perclicent. But still I am seeing this error in vault log.
After taking another look at this, the issue appears to be that Vault is attempting to contact Consul over the IPv6 loopback address–likely due to the v4 and v6 addresses being present in /etc/hosts–but Consul is only listening on the IPv4 loopback address.
You can likely resolve this through one of the following methods.
Use 127.0.0.1 instead of localhost for Consul's address in the Vault config.
backend "consul" {
address = "127.0.0.1:8500"
path = "app/vault/"
}
Configure Consul to listen on both the IPv4 and IPv6 loopback addresses.
{
"client_addr": "127.0.0.1 [::1]"
}
(Rest of the config omitted for brevity.)
Remove the localhost hostname from the IPv6 loopback in /etc/hosts
127.0.0.1 localhost
# Old hosts entry for ::1
#::1 localhost ip6-localhost ip6-loopback
# New entry
::1 ip6-localhost ip6-loopback

Vault server token login doesn't work as per lease time

We are using Hashicorp Vault with Consul and Filesystem as storage, facing issue on login every time my token duration is infinity but still ask for token need to be sealed for every few hours with again login?
config.hcl:
`ui = true
storage "consul" {
address = "127.0.0.1:8500"
path = "vault"
}
backend "file" {
path = "/mnt/vault/data"
}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}
telemetry {
statsite_address = "127.0.0.1:8125"
disable_hostname = true
}`
Token lookup:
Key Value
• -----
token **********
token_accessor ***********
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]

Fiware Orion - pepProxy

i'm part of a team that is developing an application that uses the Fiware GE's has part of the Smart-AgriFood accelerator.
We are using the Orion Context Broker for gathering the data provided by the sensor network, and we intend to use the Pep-Proxy to authenticate the sensor node for access the Orion instance. We have tried the following pepProxy's:
https://github.com/telefonicaid/fiware-orion-pep
https://github.com/ging/fi-ware-pep-proxy
We only have success implementing the second (fi-ware-pep-proxy) implementation of the proxy. With the fiware-orion-pep we haven't been able to connect to the Keystone Global instance (account.lab.fi-ware.org), we have tried the account.lab... and the cloud.lab..., my question are:
1) is the keystone (IDM) instance for authentication the account.lab or the cloud.lab?? and what port's to use or address's?
2) is the fiware-orion-pep prepared for authenticate at the account.lab.fi-ware.org?? here is way i ask this:
This one works with the curl command at >> cloud.lab.fiware.org:4730/v2.0/tokens
{
"auth": {
"passwordCredentials": {
"username": "<my_user>",
"password": "<my_password>"
}
}
}'
This one does't work with the curl comand at >> account.lab.fi-ware.org:5000/v3/auth/tokens
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"domain": {
"name": "<my_domain>"
},
"name": "<my_user>",
"password": "<my_password>"
}
}
}
} }'
3) what is the implementation that i should be using for authenticate the devices or other calls to the Orion instance???
Here are the configuration that i used:
fiware-orion-pep
config.authentication = {
checkHeaders: true,
module: 'keystone',
user: '<my_user>',
password: '<my_password>',
domainName: '<my_domain>',
retries: 3,
cacheTTLs: {
users: 1000,
projectIds: 1000,
roles: 60
},
options: {
protocol: 'http',
host: 'account.lab.fiware.org',
port: 5000,
path: '/v3/role_assignments',
authPath: '/v3/auth/tokens'
}
};
fi-ware-pep-proxy (this one works), i have set the listing port to 1026 at the source code
var config = {};
config.account_host = 'https://account.lab.fiware.org';
config.keystone_host = 'cloud.lab.fiware.org';
config.keystone_port = 4731;
config.app_host = 'localhost';
config.app_port = '10026';
config.username = 'pepProxy';
config.password = 'pepProxy';
// in seconds
config.chache_time = 300;
config.check_permissions = false;
config.magic_key = undefined;
module.exports = config;
Thanks in advance for the time ... :)
The are currently some differences in how both PEP Proxies authenticate and validate against the global instances, so they do not behave in exactly the same way.
The one in telefonicaid/fiware-orion-pep was developed to fulfill the PEP Proxy requirements (authentication and validation against a Keystone and Access Control) in individual projects with their own Keystone and Keypass (a flavour of Access Control) installations, and so it evolved faster than the one in ging/fi-ware-pep-proxy and in a slightly different direction. As an example, the former supports multitenancy using the fiware-service and fiware-servicepath headers, while the latter is transparent to those mechanisms. This development direction meant also that the functionality slightly differs from time to time from the one in the global instance.
That being said, the concrete answer:
- Both PEP Proxies should be able to contact the global instance. If one doesn't, please, fill a bug in the issues of the Github repository and we will fix it as soon as possible.
- The ging/fi-ware-pep-proxy was specifically designed for accessing the global instance, so you should be able to use it as expected.
Please, if you try to proceed with the telefonicaid/fiware-orion-pep take note also that:
- the configuration flag authentication.checkHeaders should be false, as the global instance does not currently support multitenancy.
- current stable release (0.5.0) is about to change to next version (probably today) so maybe some of the problems will solve with the update.
Hope this clarify some of your doubts.
[EDIT]
1) I have already install the telefonicaid/fiware-orion-pep (v 0.6.0) from sources and from the rpm package created following the tutorial available in the github. When creating the rpm package, this is created with the following name pep-proxy-0.4.0_next-0.noarch.rpm.
2) Here is the configuration that i used:
/opt/fiware-orion-pep/config.js
var config = {};
config.resource = {
original: {
host: 'localhost',
port: 10026
},
proxy: {
port: 1026,
adminPort: 11211
} };
config.authentication = {
checkHeaders: false,
module: 'keystone',
user: '<##################>',
password: '<###################>',
domainName: 'admin_domain',
retries: 3,
cacheTTLs: {
users: 1000,
projectIds: 1000,
roles: 60
},
options: { protocol: 'http',
host: 'cloud.lab.fiware.org',
port: 4730,
path: '/v3/role_assignments',
authPath: '/v3/auth/tokens'
} };
config.ssl = {
active: false,
keyFile: '',
certFile: '' }
config.logLevel = 'DEBUG'; // List of component
config.middlewares = {
require: 'lib/plugins/orionPlugin',
functions: [
'extractCBAction'
] };
config.componentName = 'orion';
config.resourceNamePrefix = 'fiware:';
config.bypass = false;
config.bypassRoleId = '';
module.exports = config;
/etc/sysconfig/pepProxy
# General Configuration
############################################################################
# Port where the proxy will listen for requests
PROXY_PORT=1026
# User to execute the PEP Proxy with
PROXY_USER=pepproxy
# Host where the target Context Broker is located
# TARGET_HOST=localhost
# Port where the target Context Broker is listening
# TARGET_PORT=10026
# Maximum level of logs to show (FATAL, ERROR, WARNING, INFO, DEBUG)
LOG_LEVEL=DEBUG
# Indicates what component plugin should be loaded with this PEP: orion, keypass, perseo
COMPONENT_PLUGIN=orion
#
# Access Control Configuration
############################################################################
# Host where the Access Control (the component who knows the policies for the incoming requests) is located
# ACCESS_HOST=
# Port where the Access Control is listening
# ACCESS_PORT=
# Host where the authentication authority for the Access Control is located
# AUTHENTICATION_HOST=
# Port where the authentication authority is listening
# AUTHENTICATION_PORT=
# User name of the PEP Proxy in the authentication authority
PROXY_USERNAME=XXXXXXXXXXXXX
# Password of the PEP Proxy in the Authentication authority
PROXY_PASSWORD=XXXXXXXXXXXXX
In the files above i have tried the following parameters:
Keystone instance: account.lab.fiware.org or cloud.lab.fiware.org
User: pep or pepProxy or "user from fiware account"
Pass: pep or pepProxy or "user password from account"
Port: 4730, 4731, 5000
The result it's the same as before... the telefonicaid/fiware-orion-pep is unable to authenticate:
log file at /var/log/pepProxy/pepProxy
time=2015-04-13T14:49:24.718Z | lvl=ERROR | corr=71a34c8b-10b3-40a3-be85-71bd3ce34c8a | trans=71a34c8b-10b3-40a3-be85-71bd3ce34c8a | op=/v1/updateContext | msg=VALIDATION-GEN-003] Error connecting to Keystone authentication: KEYSTONE_AUTHENTICATION_ERROR: There was a connection error while authenticating to Keystone: 500
time=2015-04-13T14:49:24.721Z | lvl=DEBUG | corr=71a34c8b-10b3-40a3-be85-71bd3ce34c8a | trans=71a34c8b-10b3-40a3-be85-71bd3ce34c8a | op=/v1/updateContext | msg=response-time: 50745 statusCode: 500
result from the client console
{
"message": "There was a connection error while authenticating to Keystone: 500",
"name": "KEYSTONE_AUTHENTICATION_ERROR"
}
I'm doing something wrong here??