From 6c77690b2898aa8a12184ca8f3c113a11c957e50 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Wed, 26 Mar 2014 18:12:00 -0400 Subject: rippled: initial pkg and module expressions rippled is the Ripple P2P payment network reference server https://ripple.com --- nixos/modules/services/misc/rippled.nix | 326 ++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 nixos/modules/services/misc/rippled.nix (limited to 'nixos/modules/services/misc') diff --git a/nixos/modules/services/misc/rippled.nix b/nixos/modules/services/misc/rippled.nix new file mode 100644 index 000000000000..7d339a48b976 --- /dev/null +++ b/nixos/modules/services/misc/rippled.nix @@ -0,0 +1,326 @@ +# configuration building is commented out until better tested. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + cfg = config.services.rippled; + + rippledStateCfgFile = "/var/lib/rippled/rippled.cfg"; + + rippledCfg = '' + [node_db] + type=HyperLevelDB + path=/var/lib/rippled/db/hyperldb + + [debug_logfile] + /var/log/rippled/debug.log + + '' + /* + + optionalString (cfg.ips != null) '' + [ips] + ${concatStringsSep "\n" cfg.ips} + + '' + + optionalString (cfg.ipsFixed != null) '' + [ips_fixed] + ${concatStringsSep "\n" cfg.ipsFixed} + + '' + */ + + optionalString (cfg.peerIp != null) '' + [peer_ip] + ${cfg.peerIp} + + [peer_port] + ${toString cfg.peerPort} + + '' + + cfg.extraConfig; + + rippledCfgFile = pkgs.writeText "rippled.cfg" rippledCfg; + +in + +{ + + ###### interface + + options = { + + services.rippled = { + + enable = mkOption { + default = false; + description = "Whether to enable rippled"; + }; + + /* + ips = mkOption { + default = [ "r.ripple.com 51235" ]; + example = [ "192.168.0.1" "192.168.0.1 3939" "r.ripple.com 51235" ]; + description = '' + List of hostnames or ips where the Ripple protocol is served. + For a starter list, you can either copy entries from: + https://ripple.com/ripple.txt or if you prefer you can let it + default to r.ripple.com 51235 + + A port may optionally be specified after adding a space to the + address. By convention, if known, IPs are listed in from most + to least trusted. + ''; + }; + + ipsFixed = mkOption { + default = null; + example = [ "192.168.0.1" "192.168.0.1 3939" "r.ripple.com 51235" ]; + description = '' + List of IP addresses or hostnames to which rippled should always + attempt to maintain peer connections with. This is useful for + manually forming private networks, for example to configure a + validation server that connects to the Ripple network through a + public-facing server, or for building a set of cluster peers. + + A port may optionally be specified after adding a space to the address + ''; + }; + */ + + peerIp = mkOption { + default = null; + example = "0.0.0.0"; + description = '' + IP address or domain to bind to allow external connections from peers. + Defaults to not binding, which disallows external connections from peers. + ''; + }; + + peerPort = mkOption { + default = 51235; + description = '' + If peerIp is supplied, corresponding port to bind to for peer connections. + ''; + }; + + /* + peerPortProxy = mkOption { + type = types.int; + example = 51236; + description = '' + An optional, additional listening port number for peers. Incoming + connections on this port will be required to provide a PROXY Protocol + handshake, described in this document (external link): + + http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt + + The PROXY Protocol is a popular method used by elastic load balancing + service providers such as Amazon, to identify the true IP address and + port number of external incoming connections. + + In addition to enabling this setting, it will also be required to + use your provider-specific control panel or administrative web page + to configure your server instance to receive PROXY Protocol handshakes, + and also to restrict access to your instance to the Elastic Load Balancer. + ''; + }; + + peerPrivate = mkOption { + default = null; + example = 0; + description = '' + 0: Request peers to broadcast your address. Normal outbound peer connections [default] + 1: Request peers not broadcast your address. Only connect to configured peers. + ''; + }; + + peerSslCipherList = mkOption { + default = null; + example = "ALL:!LOW:!EXP:!MD5:@STRENGTH"; + description = '' + A colon delimited string with the allowed SSL cipher modes for peer. The + choices for for ciphers are defined by the OpenSSL API function + SSL_CTX_set_cipher_list, documented here (external link): + + http://pic.dhe.ibm.com/infocenter/tpfhelp/current/index.jsp?topic=%2Fcom.ibm.ztpf-ztpfdf.doc_put.cur%2Fgtpc2%2Fcpp_ssl_ctx_set_cipher_list.html + + The default setting of "ALL:!LOW:!EXP:!MD5:@STRENGTH", which allows + non-authenticated peer connections (they are, however, secure). + ''; + }; + + nodeSeed = mkOption { + default = null; + example = "RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE"; + description = '' + This is used for clustering. To force a particular node seed or key, the + key can be set here. The format is the same as the validation_seed field. + To obtain a validation seed, use the rippled validation_create command. + ''; + }; + + clusterNodes = mkOption { + default = null; + example = [ "n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5" ]; + description = '' + To extend full trust to other nodes, place their node public keys here. + Generally, you should only do this for nodes under common administration. + Node public keys start with an 'n'. To give a node a name for identification + place a space after the public key and then the name. + ''; + }; + + sntpServers = mkOption { + default = null; + example = [ "time.nist.gov" "pool.ntp.org" ]; + description = '' + IP address or domain of NTP servers to use for time synchronization. + ''; + }; + + # TODO: websocket options + + rpcAllowRemote = mkOption { + default = false; + description = '' + false: Allow RPC connections only from 127.0.0.1. [default] + true: Allow RPC connections from any IP. + ''; + }; + + rpcAdminAllow = mkOption { + example = [ "10.0.0.4" ]; + description = '' + List of IP addresses allowed to have admin access. + ''; + }; + + rpcAdminUser = mkOption { + type = types.str; + description = '' + As a server, require this as the admin user to be specified. Also, require + rpc_admin_user and rpc_admin_password to be checked for RPC admin functions. + The request must specify these as the admin_user and admin_password in the + request object. + ''; + }; + + rpcAdminPassword = mkOption { + type = types.str; + description = '' + As a server, require this as the admin pasword to be specified. Also, + require rpc_admin_user and rpc_admin_password to be checked for RPC admin + functions. The request must specify these as the admin_user and + admin_password in the request object. + ''; + }; + + rpcIp = mkOption { + type = types.str; + description = '' + IP address or domain to bind to allow insecure RPC connections. + Defaults to not binding, which disallows RPC connections. + ''; + }; + + rpcPort = mkOption { + type = types.int; + description = '' + If rpcIp is supplied, corresponding port to bind to for peer connections. + ''; + }; + + rpcUser = mkOption { + type = types.str; + description = '' + Require a this user to specified and require rpcPassword to + be checked for RPC access via the rpcIp and rpcPort. The user and password + must be specified via HTTP's basic authentication method. + As a client, supply this to the server via HTTP's basic authentication + method. + ''; + }; + + rpcPassword = mkOption { + type = types.str; + description = '' + Require a this password to specified and require rpc_user to + be checked for RPC access via the rpcIp and rpcPort. The user and password + must be specified via HTTP's basic authentication method. + As a client, supply this to the server via HTTP's basic authentication + method. + ''; + }; + + rpcStartup = mkOption { + example = [ ''"command" : "log_level"'' ''"partition" : "ripplecalc"'' ''"severity" : "trace"'' ]; + description = "List of RPC commands to run at startup."; + }; + + rpcSecure = mkOption { + default = false; + description = '' + false: Server certificates are not provided for RPC clients using SSL [default] + true: Client RPC connections wil be provided with SSL certificates. + + Note that if rpc_secure is enabled, it will also be necessasry to configure the + certificate file settings located in rpcSslCert, rpcSslChain, and rpcSslKey + ''; + }; + */ + + extraConfig = mkOption { + default = ""; + description = '' + Extra lines to be added verbatim to the rippled.cfg configuration file. + ''; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + environment = { + etc = singleton + { source = rippledStateCfgFile; + target = "rippled"; + }; + + # users can attempt to send RPC commands to the server. + systemPackages = [ pkgs.rippled ]; + }; + + users.extraUsers = singleton + { name = "rippled"; + description = "Ripple server user"; + uid = config.ids.uids.rippled; + home = "/var/lib/rippled"; + }; + + systemd.services.rippled = { + path = [ pkgs.rippled ]; + + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + ExecStart = "${pkgs.rippled}/bin/rippled --fg -q --conf ${rippledStateCfgFile}"; + WorkingDirectory = "/var/lib/rippled"; + }; + }; + + networking.firewall.allowedTCPPorts = mkIf (cfg.peerIp != null) [ cfg.peerPort ]; + + system.activationScripts.rippled = '' + mkdir -p /var/{lib,log}/rippled + chown -R rippled /var/{lib,log}/rippled + ln -sf ${rippledCfgFile} ${rippledStateCfgFile} + ''; + }; +} -- cgit 1.4.1