{"id":13311805,"url":"https://github.com/AnimaGUS-minerva/fountain","last_synced_at":"2025-03-10T17:30:48.577Z","repository":{"id":45578917,"uuid":"90478266","full_name":"AnimaGUS-minerva/fountain","owner":"AnimaGUS-minerva","description":"Fountain is an ANIMA/6tisch Join Registrar, implementing RFC8995. It provides access to register new 6tisch and ANIMA nodes with a certificate using the Enrollment over Secure Transport (RFC7030) mechanism.","archived":false,"fork":false,"pushed_at":"2023-06-15T20:43:51.000Z","size":1946,"stargazers_count":1,"open_issues_count":3,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-05-01T22:45:52.620Z","etag":null,"topics":["brski","certificate-authority","ietf","rails","rfc7030","rfc8995"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AnimaGUS-minerva.png","metadata":{"files":{"readme":"README-DOCKER.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-06T17:03:02.000Z","updated_at":"2023-01-16T01:27:57.000Z","dependencies_parsed_at":"2024-10-23T13:54:25.884Z","dependency_job_id":null,"html_url":"https://github.com/AnimaGUS-minerva/fountain","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnimaGUS-minerva%2Ffountain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnimaGUS-minerva%2Ffountain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnimaGUS-minerva%2Ffountain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnimaGUS-minerva%2Ffountain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AnimaGUS-minerva","download_url":"https://codeload.github.com/AnimaGUS-minerva/fountain/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242892595,"owners_count":20202563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["brski","certificate-authority","ietf","rails","rfc7030","rfc8995"],"created_at":"2024-07-29T18:02:29.910Z","updated_at":"2025-03-10T17:30:48.102Z","avatar_url":"https://github.com/AnimaGUS-minerva.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Docker Setup for MINERVA FOUNTAIN\n\nAll of the docker configuration and build scripts are placed in the docker/\nsubdirectory.   There is no main \"Dockerfile\", in the root as is frequently\ndone because it's not as simple as that, unfortunately.\n\nA series of shell scripts invokes the appropriate Dockerfile and tags, and\npushes the result for subsequent stages.  This description applies to both\n[[doc/fountain]] and [[doc/highway]].\n\nThe shell script and Dockerfile(s) may need to be edited to use your docker\nID if you need to update the images.  Solutions sought for parameterizing\nthe Dockefile and shell scripts without introducing complexity.\n\nThe scripts are to be run in the order:\n1. docker/ruby-openssl.builder.sh\n2. docker/minerva.builder.x86_64.sh\n3. docker/fountain.build.x86_64.sh or docker/highway.build.x86_64.sh\n\nBut, if you use the shg\\_comet\\_example below, then you may not need to run\nany of them if you haven't updated any code and/or just want to run release\ntagged images.\n\nNote that there may also be ARM versions for use on home gateways.\nAll images are versioned with a \"v\", the year, and the month: as in \"v202004\"\n\n## Base Openssl extensions\n\nscript: docker/ruby-openssl.builder.sh\n\nThe Minerva toolset includes a number of patches to openssl 1.1.1, which fix\nsome issues with how DTLS works.  OpenSSL 1.1.x is also necessary to have\nECDSA support, and 1.1.1 is needed for TLS 1.3 support.\n\nIn addition, the ruby-openssl module has been extended with a CMS interface,\nwith ECIES support, and some other minor extensions to allow arbitrary\nOIDs in certificate extensions.\n\nThese things are collected together into mcr314/minerva\\_ruby\\_openssl image.\nThis is based upon a ruby 2.6.6 debian10 image.\n\nThe openssl is created by rebasing patches after each openssl release.\nThis script probably does not need to be updated.\n\n## Minerva specialized Dockerimage\n\nscript: docker/minerva.builder.x86_64.sh\n\nThe above image is further specialized with installed versions of a number of\nruby libraries that require lengthy compile steps as they extensions.\nThis has been placed into: mcr314/minerva_builder\n\n## Fountain and Highway images\n\nscript: docker/fountain.build.x86_64.sh\n\nThe fountain.build script uses the minerva.builder image.\nThe docker-ized Gemfile is used.   It contains no debug options, and it makes\nno external references, as they were loaded by the previous image.\nThis is done because some docker/deploy environments are unable to perform\nHTTPS outgoing operations without a forced MITM TLS proxy.\n\nThe resulting images are named:\n* minerva_fountain\n* minerva_highway\n\nThis final image needs to be updated each time the code changes, and should\nnot result in significant changes each time.\n\n# Deploying docker images\n\nThe highway (MASA/Comet Server) and fountain (Registrar, MUD-Supervisor) need\na few things to be deployed properly.\n\nThe common items are\n1. A database on persistent storage, and a database.yml that points to it.\n2. A persistent place to store the server certificates and private keys: /app/certificates\n3. Highway: a persistent place to store devices: /app/devices\n\nEach system needs to run a series of initialization steps.\nThose steps can be repeated each time, as they are non-destructive if run a second time.\n\nThere are quite a number of ways of doing this, including docker-composer,\nvarious kubernetes things.  These proved too annoying and complex for\ndevelopment purposes.\nWhat described below is appropriate for moderate capacity uses as it uses the\nrails \"thin\" server directly.\nIf a higher capacity system is needed, then treat each of these containers as\na worker, and create as many workers as required and put a presentation tier\n(load balancer) in front of it to spread the load.\n\nFor some detailed analysis of what a production ready systems might look\nlike, please review:\n1. https://datatracker.ietf.org/doc/draft-richardson-anima-masa-considerations/\n2. https://datatracker.ietf.org/doc/draft-richardson-anima-registrar-considerations/\n\n## Network and Database configuration\n\nThe MASA container needs a single TCP port available at a public IP (v4/v6) address.\nThis address should have a DNS name. The port number may be arbitrary, but\neither 443 or 9443 are recommended.\n\nThe Registrar container needs a single TCP port, it may also be any port,\nprovided that a Join Proxy is deployed.  It will typically be inward facing,\nand can be numbered with an IPv6 ULA, such as when used in an Autonomic\nControl Plane.  This version does not support perform the GRASP ACP announcements.\n\nThe Registrar may also provide constrained voucher service using CoAPS over a\nsingle UDP port.  The port number 5684 is recommended, but the port number\ncan also be announced via GRASP ACP announcement.\n\nBoth systems need a database.  It is possible to use sqlite3.  As containers\nare not persistent by default, if sqlite3 is used, it is recommended that it\nbe located on a third persistent volume.\nThe recommended database is postgresql, version 10 or higher.\n\nThe postgres:11.2 stock container can be used by mounting a persistent volume\non /var/lib/postgresql. The POSTGRES super-user password can be set by using\nthe \"POSTGRES_PASSWORD=xyz1234\".  Once the database container has been\nstarted, accounts can be set for each web container using:\n\n    psql -h 172.17.0.2 -U postgres\n\nuse the password specified, which above is xyz1234.\nThen create a user and database for each container, and set a password.\nThis can be done with CREATE USER / CREATE DATABASE, or with the\ncreatedb/createrole commands. (createdb, psql and createrole/createuser are\npart of postgresql-client package)\n\nI use:\n\n    docker run --mount source=staging_data,target=/var/lib/postgresql \\\n       --name staging_db \\\n       -e POSTGRES_PASSWORD=xyz1234 -d postgres:11.2\n\nThe database is then available using the name \"staging_db\" within the\ncontainers below.\n\n## setup and configuration\n\nThe arrangement described below creates a single tier\nIDevID PKI for [[doc/highway]], and single tier Domain CA for [[doc/fountain]].\nA section at the end describes how to make this a three-tier CA.\nThe MASA [[doc/highway]] signing End Entity (EE) is signed by the IDevID CA, but\nthe pledge should pin the EE certificate directly.\n\nFor the MASA [[doc/highway]] situation, the test machine is called _eeylops_.\nFor the Registrar [[doc/fountain]] situation, the test machine is called _gambol_.\n(Both are shops on Diagon Alley)\n\nAn example repo with Dockerfile is at: https://github.com/CIRALabs/shg_comet_example\n\nCreate two volumes: eeylops\\_certs and eeylops\\_devices.\n\nCreate a Dockerfile that includes:\n\n1. config/acme.yml  [[doc/highway]]\n2. config/database.yml\n3. config/environments/production.rb\n4. public/index.html\n5. turris_root [[doc/highway]]\n\n### Dockerfile\n\nIn the above example, comet/Dockerfile does these things:\n\n1. imports the build image from mcr314/minerva_highway.\n2. installs the busybox symbolic links to help with debugging.  This can be\n   skipped for a production server that should not have /bin/sh.\n3. sets the GEM_HOME and CERTDIR, to be sure they are set right.\n4. copies the files describe below into the right places. (This is really the\n   key step)\n5. Sets the command, providing the right address and port to bind to.\n\n### config/acme.yml\n\nThis file configures the ACME integration for creating IDevID certificates\nvia the IETF RFC8555 ACME protocol.   This can be used with services like letsencrypt.org.\nIf this facility is not needed, then an empty file should be created.\n\nThe hash \"dns\\_update\\_options\" should be created with the following keys:\n\nacme_server:\n: The directory URL of the ACME server that will be used.  For testing, one\ncan safely use the staging server at: https://acme-staging-v02.api.letsencrypt.org/directory.\nIt will issue certificates, but they will not be against a deployed trust\nanchor.  To use the production LE server, remote the \"staging-\"\n\nmaster:\n: This is the IP address of the DNS master for the zone that will be used. A\nTSIG authenticated DNS Update (RFC3007, aka Dynamic Update) will be done to this server.\n\nkey_name:\n: The key name that will be used for authenticating. The key type should be\nprefixed with the key name.  An HMAC-SHA256 key is recommended.\n\nsecret:\n: The secret value to be used.  Typically this is a random value generated\nand base64 encoded using something like:\n\n    dd if=/dev/random bs=1 count=32 | base64\n\nor a program like \"pwgen 48 1\".\n\nprint_only:\n: This should be set to false in production.  If set to true, then the calls\nto do DNS Updates via the \"nsupdate\" program will be put into debug mode.\n\n\nAs an example:\n\n    dns_update_options:\n      acme_server: \"https://acme-staging-v02.api.letsencrypt.org/directory\"\n      master: '198.51.100.18'\n      key_name: 'hmac-sha256:keyname'\n      secret:  'A7thedmnicetPJsecretIRbvaluecQ7youiRsuseWtforTgthePUDTSIG4valuef'\n      print_only: false\n\nThis goes with a BIND9 configuration containing:\n\n    key keyname. {\n            algorithm hmac-sha256;\n            secret:  'A7thedmnicetPJsecretIRbvaluecQ7youiRsuseWtforTgthePUDTSIG4valuef';\n    };\n\n    zone \"example.org\" {\n            type master;\n            file \"example.org.signed\";\n\n            key-directory \"/etc/domain/example.org\";\n            inline-signing yes;\n            auto-dnssec maintain;\n\n            # Then, in the \"zone\" definition statement for \"example.org\",\n            # place an \"update-policy\" statement like this one, adjusted as\n            # needed for your preferred permissions:\n            update-policy {\n                      grant keyname. subdomain r.example.org. ANY;\n            };\n\n    };\n\nIn order to specify the zone, \"example.org\", and the suffix \"r\"\n[it should have been called a prefix perhaps, except that DNS names go left-to-right]\nthen the database system variables are used.\n\nThe key can be called anything rather than \"keyname\". Note where the trailing\nperiod is significant and where it does not belong.\n\nThere is inconsistent between settings up some of the .yml file contents and\nentering things in the database, and a future version will put more into the\nthe database only.\nThe TSIG key will remain in acme.yml in order to avoid putting significant TSIG keys into\nthe database.\n\nThe two variables that are needed to be set are:\n\nshg\\_suffix:\n: Set this to \"r\", to get \"r.example.org\"\n\nshg\\_zone:\n: Set this to \"example.org\"\n\nThese are currently setup in the example \"staging.sh\" file using the highway:h0\\_shg\\_zone.\n\nDevices which register will be given names like _nXXYYZZ.r.example.org_ based\nupon a ULA that contains *fdXX:YYZZ:*\n\n### config/database.yml\n\nThis is a YAML file that sets up the connection to the database.\nAs an example:\n\n    production:\n      adapter: postgresql\n      database: shg_comet_staging\n      username: shg_comet_staging\n      password: *THEPASSWORD*\n      encoding: utf8\n      host: postgres\n      reconnect: true\n\nThis would connect to the database called _shg\\_comet\\_staging_ running on\nthe host _postgres_.\nThe database should already exist, but it may be empty provided that the\nnamed user has the proper rights to create tables.  The migration process\nwill create the tables and populate them.\n\nTo use an sqlite3 database, located on a persistant mount at /app/database:\n\n    production:\n     adapter: sqlite3\n     database: /app/database/production.sqlite3\n     pool: 5\n     timeout: 5000\n\n\n### config/environments/production.rb\n\nTake this file from the example.\nPlease adjust the SMTP server information to something that works, and please\nset the destination address for information emails.\n\nThere are very few things you want to tweak, but at the bottom are several\nimportant settings:\n\n    $TOFU_DEVICE_REGISTER = true\n    $REVISION= \"docker\"\n\n    $INTERNAL_CA_SHG_DEVICE=false\n    $LETSENCRYPT_CA_SHG_DEVICE=true\n\nIf you want to use LetsEncrypt as your CA, then select true, and make sure\nthat acme.yml is setup.  If an internal CA suits you (more control over the\nIDevID), then select that.\n\nOne can use [LetsEncrypt](doc/ACME-HACKS.md) to setup the\n\nThe Revision variable can be set to any useful value, if not set there is a\nvalue in the environment which is incremented on each release.\n\nThe above settings should probably become SystemVariables, to live in the\ndatabase rather than as configuration values.\n\n#### TOFU DEVICE REGISTER\n\nThe TOFU\\_DEVICE\\_REGISTER setting controls if unknown new SHG routers will\nbe accepted.\nIf so, then the device information is collected, but will be marked\n\"obsolete\" until an administrator enables it.\nThis is not always what people think of as TOFU, but it is how SSH works.\nThe device may have to be rebooted after it is authorized so that it will\ntry again, if a long time has passed since it tried the first time.\n\nIf this is not set, then unknown devices get a 404 and no information is\ncollected, which makes it hard to enable them.\n\nTo enable the device, use the \"eeylops.sh\" (or your equivalent) script, and run:\n\n    ./eeylops.sh bundle exec rake shg:valid PRODUCTID=aa:bb:cc:dd:ee:ff\n\nTo get a list of devices, do:\n\n    ./eeylops.sh bundle exec rake highway:list_dev\n\n### public/index.html\n\nThis file may contain any useful information.\nIt will be displayed to curious visitors who hit the front of the URL used.\nIt is suggested that it be used to point to project information.\n\n### turris_root\n\nThis directory can contain any additional files or patches that should be\nreturned to each SHG router that is provisioned.\nDuring the provisioning process, a tar file is created with the new device\ncertificate, and the contents of this directory are added.\nThe contents are extracted in the root directory, so some significant caution\nis waranteed.\n\nIn the example provided, the file /root/.ssh/authorized_keys is installed\nwith mcr@sandelman.ca's public key to enable remote login for debugging.\n\nThere is a provided etc/shg/postinst.sh script which will look for files\nin etc/shg/extra, and if a file exists, will append that file to an existing\nfile rather than append to it.   This is used in this example to enable SSH\naccess to the Turris from Sandelman's test office network.\n\nThe above two changes provide for being able to remote manage the device\nsecurely without any actions, and are probably inappropriate for many\nsituations.  They do not represent a default password, and specifically avoid\nhaving a default maintenance password set!\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAnimaGUS-minerva%2Ffountain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAnimaGUS-minerva%2Ffountain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAnimaGUS-minerva%2Ffountain/lists"}