From f536d190342ee9b2a8375c6f04c66bdc3a2b3593 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 27 Apr 2024 01:16:05 +1000 Subject: [PATCH] feat: generate consul policy/tokens - generate policy/token to add nodes - generate policy/token for all nodes - add base::root profile to manage aspects of the root user --- hieradata/common.eyaml | 4 ++ hieradata/common.yaml | 1 + .../au/region/syd1/infra/storage/consul.eyaml | 2 - site/profiles/manifests/base.pp | 2 + site/profiles/manifests/base/root.pp | 13 +++++ site/profiles/manifests/consul/client.pp | 53 +++++++++++++++++++ site/profiles/manifests/consul/policies.pp | 23 ++++++++ site/profiles/manifests/consul/server.pp | 4 +- site/profiles/manifests/consul/tokens.pp | 13 +++++ 9 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 site/profiles/manifests/base/root.pp create mode 100644 site/profiles/manifests/consul/client.pp create mode 100644 site/profiles/manifests/consul/policies.pp create mode 100644 site/profiles/manifests/consul/tokens.pp diff --git a/hieradata/common.eyaml b/hieradata/common.eyaml index 91e63a8..bf97631 100644 --- a/hieradata/common.eyaml +++ b/hieradata/common.eyaml @@ -1,3 +1,7 @@ --- profiles::accounts::sysadmin::password: ENC[PKCS7,MIIBqQYJKoZIhvcNAQcDoIIBmjCCAZYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAoS7GyofFaXBNTWU+GtSiz4eCX/9j/sh3fDDRgOgNv1qpcQ87ZlTTenbHo9lxeURxKQ2HVVt7IsrBo/SC/WgipAKnliRkkIvo7nfAs+i+kEE8wakjAs0DcB4mhqtIZRuBkLG2Nay//DcG6cltVkbKEEKmKLMkDFZgTWreOZal8nDljpVe1S8QwtwP4/6hKTef5xsOnrisxuffWTXvwYJhj/VXrjdoH7EhtHGLybzEalglkVHEGft/WrrD/0bwJpmR0RegWI4HTsSvGiHgvf5DZJx8fXPZNPnicGtlfA9ccQPuVo17bY4Qf/WIc1A8Ssv4kHSbNIYJKRymI3UFb0Z4wzBsBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBBxDLb6pCGbittkcX6asd/gEBmMcUNupDjSECq5H09YA70eVwWWe0fBqxTxrr2cXCXtRKFvOk8SJmL0xHAWodaLN9+krTWHJcWbAK8JXEPC7rn] profiles::accounts::root::password: ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAM79PRxeAZHrDcSm4eSFqU94/LjuSbdUmJWivX/Pa8GumoW2e/PT9nGHW3p98zHthMgCglk52PECQ+TBKjxr+9dTyNK5ePG6ZJEqSHNRqsPGm+kfQj/hlTmq8vOBaFM5GapD1iTHs5JFbGngI56swKBEVXW9+Z37BjQb2xJuyLsu5Bo/tA0BaOKuCtjq1a6E38bOX+nJ+YF1uZgV9ofAEh1YvkcTmnEWYXFRPWd7AaNcWn03V2pfhGqxc+xydak620I47P+FE+qIY72+aQ6tmLU3X9vyA1HLF2Tv572l4a2i+YIk6nAgQdi+hQKznqNL9M9YV+s1AcmcKLT7cfLrjsjA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCMWrdCWBQgtW3NOEpERwP+gBA3KDiqe4pQq6DwRfsEXQNZ] +profiles::consul::client::secret_id_salt: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAS7pNFRX4onccFaR87zB/eFFORuF22j6xqjyeAqqjgEduYhkt6w5kkz+YfUoHUesU0Q6F2p6HrCSZ8yAsx5M25NCiud9P4hIpjKmOZ4zCNO7uhATh4AQDYw3BrdRwfO+c6jOl5wOiNLCfDBJ0sFT3akCvcuPS1xIoRJq4Gyn+uCbOsMbvSl25ld2xKt1/cqs8gc1d8mkpjwWto7t+qZSUFMCehTbehH3G4a3Q5rvfBoNwv42Wbs676BDcCurDaAzHNqE7pDbOWhGuVOBl+q+BU0Ri/CRkGcTViN9fr8Dc9SveVC6EPsMbw+05/8/NlfzQse3KAwQ34nR9tR2PQw5qEzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBB7LywscQtF7cG2nomfEsu9gDDVqJBFP1jAX2eGZ2crYS5gnBcsRwhc0HNo2/WWdhZprMW+vEJOOGXDelI53NxA3o0=] +profiles::consul::token::node_editor::secret_id: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAO8IIF2r18dFf0bVKEwjJUe1TmXHH0AIzsQHxkHwV7d37kvH1cY9rYw0TtdHn7GTxvotJG7GZbWvbunpBs1g2p2RPADiM6TMhbO8mJ0tAWLnMk7bQ221xu8Pc7KceqWmU17dmgNhVCohyfwJNqbA756TlHVgxGA0LtNrKoLOmgKGXAL1VYZoKEQnWq7xOpO+z3e1UfjoO6CvX/Od2hGYfUkHdro8mwRw4GFKzU7XeKFdAMUGpn5rVmY3xe+1ARXwGFaSrTHzk2n85pvwhPRlQ+OwqzyT19Qo2FNeAO6RoCRIFTtqbsjTWPUlseHIhw4Q5bHO1I0Mrlm5IHDESw/22IzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCEe9wD72qxnpeq5nCi/d7BgDCP29sDFObkFTabt2uZ/nF9MT1g+QOrrdFKgnG6ThnwH1hwpZPsSVgIs+yRQH8laB4=] +profiles::consul::server::acl_tokens_initial_management: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAi1UH7AZirJ1PdxWy+KEgS5ufm0wbn2xy9rkg14hKYpcVjBa4pOZpSLMGMiiUpBIqBytDMZM4ezYa/luktpkBImJbM/TE16beGtsacQGA+9eZk2Tihs9GR2qbAQiu5lLITiDlwNnf0GeWdqHM8CTeD68DczQF320d9U14/k6pG/7z+w/MGLcjsQoSuOFTm42JVn1BI46t1CYSCHMXQc/9Tfs+FzI+vumohI8DxAYBIuyzU5HBX/MntAsvD/yixMJS1pZL9WwgqZJC/wK34rVRB39DpxWf/WROrI+WLuSJwr7WBjaeF9Ju+89WKCgsI53EWhFTj8GgDZm/jqPoE478NjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAoACRzJdQKNYXZv6cghFIIgDAzB81DMcuY815nb8POtZpiA06jT/068AoZmSctHoFK/zW9tY229N5r1Tb+WHElqLk=] +profiles::consul::server::acl_tokens_default: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAh4Ag95xgkIZHL0gP9OLnZauih0dB1/2l9Jzw8mP3OiIv7fw23otHYONlS3Emtj7oxW8MKcZGKDCzwCT6T2p+V5wx1n15wr2J+FmL24VbclJwrMPQ4AdgP359B9h21uoyo7Zdy7RuuvLfkU1fWXbs3SeWbi2HJs1Ed1/oI1jzr3OgwMbVtbyzd1VuAXeZ9bHQG3IA8z+w/k5m61th0HTyHjw7eldQulbohDuwv545z9axHEoHKCRT2a3ZwBufV2ST6Dm3g9GERzXE9Adp9DQC5adqM74wfsujOMLK2QFJSSIOj2uCs1CpEnrNrQ8zjP3fudM2z3l7KdSHZazEamCSxTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBY/Tn9tzEKYc5dxnzP2rP7gDBWKgVP3lf2T4Q0WPQt3ns0E6RUSO6OtBegb/5qDyohY2nsDeJTnMKOYzYt/J1PhnY=] diff --git a/hieradata/common.yaml b/hieradata/common.yaml index c1c6138..9fa4d12 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -84,6 +84,7 @@ profiles::dns::master::basedir: '/var/named/sources' profiles::dns::base::ns_role: 'roles::infra::dns::resolver' profiles::dns::base::use_ns: 'region' profiles::consul::server::members_role: roles::infra::storage::consul +profiles::consul::token::node_editor::accessor_id: '024e27bd-c5bb-41e7-a578-b766509e11bc' profiles::packages::install: - bash-completion diff --git a/hieradata/country/au/region/syd1/infra/storage/consul.eyaml b/hieradata/country/au/region/syd1/infra/storage/consul.eyaml index 3d28bc6..fd508a6 100644 --- a/hieradata/country/au/region/syd1/infra/storage/consul.eyaml +++ b/hieradata/country/au/region/syd1/infra/storage/consul.eyaml @@ -1,4 +1,2 @@ --- profiles::consul::server::gossip_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEADwwYLK+fU0M/uLqQpRjHnIAyrt6yPEZSXpUX2jvOGVOA63X8LOYpLVfEGWMmkZ7BHRO0fgr847UUI/xI8otIuiOpgtW2E7QLWs806KUNXz+L8c7kSnQ1XAD5R81/5joDHl4AIxl5fAGryTXH1gfnpTMWh2yjFzU/KYuk2GhrU0M9ewCGJErQG4pT4u3ymGmkLjx6AiZ8r9xb4Eos2bhCCpFWfyb0kKcJqdKU9mzy508byNCfp8lr1DoKxEQrdqSSAQdepn6wCgBZtlAK/k63tOqM9dxyDaCsK8vLG9LlvuEwi3OL2lzTtc1mAcdYxahDo3uBX0/VcCswaXq3nPnu3TBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCUwXPoMh/dylvFwyRzAsnRgDDvh5CHrzJYdUXWGsauYlifOOukYokkwG3yqqtCByveMqVWfWsQukiDTixdqpCgfzw=] -profiles::consul::server::acl_tokens_initial_management: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAi1UH7AZirJ1PdxWy+KEgS5ufm0wbn2xy9rkg14hKYpcVjBa4pOZpSLMGMiiUpBIqBytDMZM4ezYa/luktpkBImJbM/TE16beGtsacQGA+9eZk2Tihs9GR2qbAQiu5lLITiDlwNnf0GeWdqHM8CTeD68DczQF320d9U14/k6pG/7z+w/MGLcjsQoSuOFTm42JVn1BI46t1CYSCHMXQc/9Tfs+FzI+vumohI8DxAYBIuyzU5HBX/MntAsvD/yixMJS1pZL9WwgqZJC/wK34rVRB39DpxWf/WROrI+WLuSJwr7WBjaeF9Ju+89WKCgsI53EWhFTj8GgDZm/jqPoE478NjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAoACRzJdQKNYXZv6cghFIIgDAzB81DMcuY815nb8POtZpiA06jT/068AoZmSctHoFK/zW9tY229N5r1Tb+WHElqLk=] -profiles::consul::server::acl_tokens_default: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAh4Ag95xgkIZHL0gP9OLnZauih0dB1/2l9Jzw8mP3OiIv7fw23otHYONlS3Emtj7oxW8MKcZGKDCzwCT6T2p+V5wx1n15wr2J+FmL24VbclJwrMPQ4AdgP359B9h21uoyo7Zdy7RuuvLfkU1fWXbs3SeWbi2HJs1Ed1/oI1jzr3OgwMbVtbyzd1VuAXeZ9bHQG3IA8z+w/k5m61th0HTyHjw7eldQulbohDuwv545z9axHEoHKCRT2a3ZwBufV2ST6Dm3g9GERzXE9Adp9DQC5adqM74wfsujOMLK2QFJSSIOj2uCs1CpEnrNrQ8zjP3fudM2z3l7KdSHZazEamCSxTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBY/Tn9tzEKYc5dxnzP2rP7gDBWKgVP3lf2T4Q0WPQt3ns0E6RUSO6OtBegb/5qDyohY2nsDeJTnMKOYzYt/J1PhnY=] diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 5d30011..a387570 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -22,6 +22,7 @@ class profiles::base ( include profiles::base::scripts include profiles::base::hosts include profiles::base::groups + include profiles::base::root include profiles::accounts::sysadmin include profiles::ntp::client include profiles::dns::base @@ -29,6 +30,7 @@ class profiles::base ( include profiles::cloudinit::init include profiles::metrics::default include profiles::helpers::node_lookup + include profiles::consul::client # include the python class class { 'python': diff --git a/site/profiles/manifests/base/root.pp b/site/profiles/manifests/base/root.pp new file mode 100644 index 0000000..d53951e --- /dev/null +++ b/site/profiles/manifests/base/root.pp @@ -0,0 +1,13 @@ +# manage the root user +class profiles::base::root { + + # TODO + # for now, add some root directories + + file {'/root/.config': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0600', + } +} diff --git a/site/profiles/manifests/consul/client.pp b/site/profiles/manifests/consul/client.pp new file mode 100644 index 0000000..edfd1ec --- /dev/null +++ b/site/profiles/manifests/consul/client.pp @@ -0,0 +1,53 @@ +# profiles::consul::client +class profiles::consul::client ( + String $secret_id_salt = '', + Stdlib::Fqdn $consul_hostname = 'consul.service.consul', + Enum['http','https'] $consul_protocol = 'http', + Stdlib::Port $consul_port = 8500, + String $consul_api_token = lookup('profiles::consul::server::acl_tokens_initial_management'), +) { + + # Create ACL policy that allows nodes to update themselves and read others + consul_policy { $facts['networking']['hostname']: + description => "${facts['networking']['fqdn']} puppet-generated-policy", + rules => [ + { + 'resource' => 'node', + 'segment' => $facts['networking']['hostname'], + 'disposition' => 'write' + }, + { + 'resource' => 'node', + 'segment' => '', + 'disposition' => 'read' + } + ], + acl_api_token => $consul_api_token, + hostname => $consul_hostname, + protocol => $consul_protocol, + port => $consul_port, + } + + consul_token { $facts['networking']['hostname']: + accessor_id => fqdn_uuid($facts['networking']['fqdn']), + description => "${facts['networking']['fqdn']} puppet-generated-token", + policies_by_name => [$facts['networking']['hostname']], + acl_api_token => $consul_api_token, + secret_id => fqdn_uuid("${facts['networking']['fqdn']}-${secret_id_salt}"), + hostname => $consul_hostname, + protocol => $consul_protocol, + port => $consul_port, + + } + + # ensure the consul token is saved for the root user + file {'/root/.config/consul_node_token': + ensure => file, + owner => 'root', + group => 'root', + mode => '0600', + content => Sensitive(fqdn_uuid("${facts['networking']['fqdn']}-${secret_id_salt}")), + require => File['/root/.config'], + } + +} diff --git a/site/profiles/manifests/consul/policies.pp b/site/profiles/manifests/consul/policies.pp new file mode 100644 index 0000000..df1bf2a --- /dev/null +++ b/site/profiles/manifests/consul/policies.pp @@ -0,0 +1,23 @@ +# profiles::consul::policies +class profiles::consul::policies ( + String $root_api_token = lookup('profiles::consul::server::acl_tokens_initial_management'), +) { + + consul_policy { 'node_editor': + description => 'Policy to read/write all nodes puppet-generated-policy', + rules => [ + { + 'resource' => 'node', + 'segment' => '', + 'disposition' => 'write' + }, + { + 'resource' => 'node', + 'segment' => '', + 'disposition' => 'read' + } + ], + acl_api_token => $root_api_token, + hostname => $facts['networking']['ip'], + } +} diff --git a/site/profiles/manifests/consul/server.pp b/site/profiles/manifests/consul/server.pp index 97137a4..b3ec8c7 100644 --- a/site/profiles/manifests/consul/server.pp +++ b/site/profiles/manifests/consul/server.pp @@ -105,8 +105,10 @@ class profiles::consul::server ( # consul before extra services if defined(Class['consul']) { - # setup nginx + # include nginx, policies and tokens include profiles::consul::nginx + include profiles::consul::policies + include profiles::consul::tokens # get the dns port from the $ports hash, otherwise use the default $dns_port = pick($ports['dns'], 8600) diff --git a/site/profiles/manifests/consul/tokens.pp b/site/profiles/manifests/consul/tokens.pp new file mode 100644 index 0000000..c471783 --- /dev/null +++ b/site/profiles/manifests/consul/tokens.pp @@ -0,0 +1,13 @@ +# profiles::consul::tokens +class profiles::consul::tokens ( + String $root_api_token = lookup('profiles::consul::server::acl_tokens_initial_management'), +){ + + consul_token { 'node_editor': + accessor_id => lookup('profiles::consul::token::node_editor::accessor_id'), + policies_by_name => ['node_editor'], + acl_api_token => $root_api_token, + secret_id => lookup('profiles::consul::token::node_editor::secret_id'), + hostname => $facts['networking']['ip'], + } +}