diff --git a/hive.nix b/hive.nix index 2f7636b..bf946e9 100644 --- a/hive.nix +++ b/hive.nix @@ -85,7 +85,7 @@ in }; lagon = { name, nodes, ... }: { - deployment.tags = [ "keycloak" ]; + deployment.tags = [ "keycloak" "wayf" ]; deployment.targetHost = "lagon.federez.net"; networking.hostName = name; federez.monitoring.apiKey = "f85dcb12-970c-4ea1-99b4-01e2fc26bc6c"; @@ -97,7 +97,7 @@ in imports = [ ./profiles/vm.nix - ./profiles/keycloak.nix + ./profiles/wayf.nix ]; }; diff --git a/npins/sources.json b/npins/sources.json index 45536de..a651066 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -24,6 +24,18 @@ "url": "https://github.com/nix-community/disko/archive/d07de570ba05cec2807d058daaa044f6955720c7.tar.gz", "hash": "18rli5h2xmzbbwambrcrg7r22vp0rmnjm55mcqc00n3fq5kscsqy" }, + "nix-phps": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "fossar", + "repo": "nix-phps" + }, + "branch": "master", + "revision": "509bc62c91ecf1767b0e0142373d069308cf86c5", + "url": "https://github.com/fossar/nix-phps/archive/509bc62c91ecf1767b0e0142373d069308cf86c5.tar.gz", + "hash": "0s548v1vylqdw8a5vlzz12gxjklcyqzckvbma2a3z539sfg4iils" + }, "nixpkgs": { "type": "Channel", "name": "nixos-unstable-small", diff --git a/pkgs/switchwayf.nix b/pkgs/switchwayf.nix index 6130b28..7a3a2e7 100644 --- a/pkgs/switchwayf.nix +++ b/pkgs/switchwayf.nix @@ -15,6 +15,12 @@ stdenv.mkDerivation rec { hash = "sha256-SqJzkV7dJXPUrY/9pz54VYxd8eAv+aFDik9F3N4WBIg="; }; + installPhase = '' + mkdir -p $out/ + cp -r www $out/ + ln -s $out/www/WAYF $out/www/WAYF.php + ''; + meta = with lib; { description = "SAML Identity Provider Discovery Service implementation developed by SWITCH"; homepage = "https://gitlab.switch.ch/aai/SWITCHwayf"; diff --git a/profiles/switch-config.php b/profiles/switch-config.php new file mode 100644 index 0000000..11d9879 --- /dev/null +++ b/profiles/switch-config.php @@ -0,0 +1,324 @@ + or if the assertion consumer url + // check below is enabled + // Requires $useSAML2Metadata to be true + //$enableDSReturnParamCheck = true; + + // If true, the return parameter is checked for Service Providers that + // don't have and extension set. Instead of this + // extension, the hostnames of the assertion consumer URLs are used to check + // the return parameter against. + // This feature is useful in case the Service Provider's metadata doesn't contain + // a extension. It increases security for Service + // Provider's that don't have an extensions. + // Requires $useSAML2Metadata and $enableDSReturnParamCheck to be true + //$useACURLsForReturnParamCheck = false; + +// Whether to turn on Kerberos support for Identity Provider preselection +//$useKerberos = false; + + // A Kerboros-protected page that redirects back to the WAYF script + //$kerberosRedirectURL = '/myFederation/kerberosRedirect.php'; + +// If enabled, the user's IP is used for a reverse DNS lookup whose resulting +// domain name then is matched with the URN values of the Identity Providers +//$useReverseDNSLookup = false; + +// Whether the JavaScript required for embedding the WAYF +// on a remote site should be generated or not +// Lowers security against phising! +// If this value is set to true, any web page in the world can +// (with some efforts) find out with a high probability from which +// organization a user is from. This could be misused for phishing attacks. +// Therefore, only enable this feature if you know what you are doing! +//$useEmbeddedWAYF = false; + + // If enabled the Embedded WAYF will prevent releasing information + // about the user's preselected Identity Provider + // While this is benefical to the data protection of the user, it will also + // prevent preselecting the user's Identity Provider. Thus, users will have + // to preselect their IdP each and every time + // Requires $useEmbeddedWAYF to be true + //$useEmbeddedWAYFPrivacyProtection = false; + + // If enabled, the referer hostname of the request must match an assertion + // consumer URL or a discovery URL of a Service Provider in $metadataSPFile + // in order to let the Embedded WAYF preselect an Identity Provider. + // Therefore, this option is a good compromise between data protection and + // userfriendlyness. + // Requires $useSAML2Metadata to be true and $useEmbeddedWAYFPrivacyProtection + // to be false + //$useEmbeddedWAYFRefererForPrivacyProtection = false; + +// If enabled (default) Identity Providers that are in the +// "Hide From Discovery" entity category (see +// https://refeds.org/category/hide-from-discovery/) will not +// be parsed when SAML2 metadata is processed. The effect will +// be that these IdPs are not shown in the organisation drop +// down list. IdPs in this entity category, however, still can +// be manually added using the Embedded WAYF. +//$supportHideFromDiscoveryEntityCategory = true; + +// Only process IDPs with a particular entity category. All +// others are ignored and not taken into account. +// Multiple entity category identifiers can be provided +// space separated. If the IdP is in none of them, +// the IdP is ignored. +//$filterEntityCategory = 'http://example.com/category/example-member'; + +// Whether or not to add the entityID of the preselected IdP to the +// exported JSON/Text/PHP Code +// Lowers security against phising! +// If this value is set to true, any web page +// in the world can easily find out with a high probability from which +// organization a user is from. This could be misused for phishing attacks. +// Therefore, only enable this feature if you know what you are doing! +//$exportPreselectedIdP = false; + +// Whether to enable logging of WAYF/DS requests +// If turned on make sure to also configure $WAYFLogFile +//$useLogging = true; + + // Where to log the access requests + // This log is only an audit log for access requests. + // Errors (e.g. when parsing SAML metadata) go to the syslog. + // Make sure the web server user has write access to this file! + //$WAYFLogFile = '/var/log/apache2/wayf.log'; + +// if set, errors intended for end users will trigger a redirection to a +// dedicated service instead of being displayed locally, as possible with +// Shibboleth SP: +// https://shibboleth.atlassian.net/wiki/spaces/SP3/pages/2065334361/Errors#Errors-Redirection +// the following variables are available, and will be substituded in the URL: +// - $time: current date and time +// - $type: the error message localization code +// - $message: the localized error message +// - $url: the URL associated with the request +// - $entityID: name of service provider, if known +// - $contactName: name of first technical contact for service provider, if known +// - $contactEmail: email of first technical contact for service provider, if known +//$errorRedirectURL = 'https://error.example.com?now=$time&errorType=$type&errorText=$message&entityID=$entityID'; + + +// 4. Files and path Settings +//*************************** +// all relatives paths are resolved relatively to configuration directory + +// Set both config files to the same value if you don't want to use the +// the WAYF to read a (potential) automatically generated file that undergoes +// some plausability checks before being used +//$IDPConfigFile = 'IDProvider.conf.php'; +//$backupIDPConfigFile = 'IDProvider.conf.php'; + +// Use $metadataFile as source federation's metadata. +//$metadataFile = '/etc/shibboleth/metadata.myFederation.xml'; + +// File to store the parsed IdP list +// Will be updated automatically if the metadataFile modification time +// is more recent than this file's +// The user running the script must have permission to create $metadataIdpFile +//$metadataIDPFile = 'IDProvider.metadata.php'; + +// File to store the parsed SP list. +// Will be updated automatically if the metadataFile modification time +// is more recent than this file's +// The user running the script must have permission to create $metadataIdpFile +//$metadataSPFile = 'SProvider.metadata.php'; + +// File to use as the lock file for writing the parsed IdP and SP lists. +// The user running the script must have permission to write $metadataLockFile +//$metadataLockFile = '/tmp/wayf_metadata.lock'; + +// Use an absolute URL in case you want to use the embedded WAYF +// The default assumes that this is in the same directory like +// the WAYF script. +//$imageURL = 'https://ds.example.org/SWITCHwayf/images'; + +// Absolute URL to point to css directory +// The default assumes that this is in the same directory like +// the WAYF script. +//$cssURL = 'https://ds.example.org/SWITCHwayf/css'; + +// Absolute URL to point to javascript directory +// The default assumes that this is in the same directory like +// the WAYF script. +//$javascriptURL = 'https://ds.example.org/SWITCHwayf/js'; + +// Abolute URL to point to APIs +//$apiURL = 'https://ds.example.org/SWITCHwayf/api.php'; + +// 5. Appearance Settings +//************************** + +// Identifier for this particular instance of the SWITCHwayf +// This is mainly used for logging to syslog and in particular +// useful in case multiple instances of the SWITCHwayf are +// operated on the same host +//$instanceIdentifier = 'SWITCHwayf'; + +// URL to send user to when clicking on federation logo +// Insert %s as macro to be substituted by the language (e.g. 'en', 'de', 'fr', ...) the WAYF uses +// Set to an empty string to hide the logo +//$federationURL = 'http://www.example.org/myFed/'; + +// Absolute URL to the federation logo that should be displayed in the Embedded WAYF +// Set to an empty string to hide the logo +//$logoURL = 'http://ds.example.org/SWITCHwayf/images/federation-logo.png'; + +// Absolute URL to the small federation logo that should be displayed in the +// embedded WAYF. Make sure the dimensions (in particular the height of the logo) +// is small, ideally not larger than 120x30 pixel +//$smallLogoURL = 'http://ds.example.org/SWITCHwayf/images/small-federation-logo.png'; + +// Support contact email address +//$supportContactEmail = 'helpdesk@example.org'; + +// Absolute URL to the logo of the organization operating this Discovery Service +// Set to an empty string to hide the logo +//$organizationLogoURL = 'https://ds.example.org/SWITCHwayf/images/organization-logo.png'; + +// Absolute URL to the organization's web page +// Insert %s as macro to be substituted by the language (e.g. 'en', 'de', 'fr', ...) the WAYF uses +//$organizationURL = 'http://www.example.org/'; + +// Absolute URL to an FAQ page +// This entries local string is 'faq' in languages.php +// Insert %s as macro to be substituted by the language (e.g. 'en', 'de', 'fr', ...) the WAYF uses +// Set to an empty string to hide the logo +//$faqURL = 'http://www.example.org/%s/myFed/faq/'; + +// Absolute URL to a help/support page +// Insert %s as macro to be substituted by the language (e.g. 'en', 'de', 'fr', ...) the WAYF uses +// Set to an empty string to hide the logo +//$helpURL = 'http://www.example.org/%s/myFed/help/'; + +// Absolute URL to a privacy policy page +// Insert %s as macro to be substituted by the language (e.g. 'en', 'de', 'fr', ...) the WAYF uses +// Set to an empty string to hide the logo +//$privacyURL = 'http://www.example.org/%s/myFed/privacy/'; + +// Additional strings form custom templates +//$customStrings = array( +// 'federationName' = 'myFederation' +//); + + +// Development mode settings +//************************** +// If the development mode is activated, PHP errors and warnings will be displayed +// on pages the SWITCHwayf generates +//$developmentMode = true; diff --git a/profiles/wayf.nix b/profiles/wayf.nix new file mode 100644 index 0000000..221f79c --- /dev/null +++ b/profiles/wayf.nix @@ -0,0 +1,79 @@ +{ config, pkgs, ... }: +let + sources = import ../npins; + phps = import sources.nix-phps; +in +{ + nixpkgs.overlays = [ + (self: super: { + switchwayf = super.callPackage ../pkgs/switchwayf.nix { }; + }) + ]; + + networking.firewall.allowedTCPPorts = [ 80 443 ]; + services.nginx = { + enable = true; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedProxySettings = true; + + virtualHosts."sso.federez.net" = { + enableACME = true; + forceSSL = true; + + root = "${pkgs.switchwayf}/www/"; + locations."~ \\.php" = { + root = "${pkgs.switchwayf}/www/"; + extraConfig = '' + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_index WAYF.php; + fastcgi_pass unix:${config.services.phpfpm.pools.switchwayf.socket}; + include ${config.services.nginx.package}/conf/fastcgi.conf; + include ${config.services.nginx.package}/conf/fastcgi_params; + + ''; + }; + # locations."~ /wayf/\\.php".extraConfig = '' + # fastcgi_split_path_info ^(.+\.php)(/.+)$; + # fastcgi_pass unix:${config.services.phpfpm.pools.switchwayf.socket}; + # include ${config.services.nginx.package}/conf/fastcgi.conf; + # include ${config.services.nginx.package}/conf/fastcgi_params; + # ''; + + }; + }; + + users.users.switchwayf = { + isSystemUser = true; + group = "nginx"; + }; + + users.groups.nginx = {}; + + services.phpfpm.pools.switchwayf = { + user = "switchwayf"; + group = "nginx"; + + settings = { + pm = "dynamic"; + "listen.owner" = "nginx"; + "pm.max_children" = 10; + "pm.start_servers" = 1; + "pm.min_spare_servers" = 1; + "pm.max_spare_servers" = 1; + }; + + # XXX(raitobezarius): I don't allow anyone to go in real production with this. + phpPackage = phps.packages.${builtins.currentSystem}.php74; + + phpEnv = { + backupIDPConfigFile = "/var/lib/switchwayf/IDProvider.conf.php"; + metadataIDPFile = "/var/lib/switchwayf/IDProvider.metadata.conf.php"; + metadataSPFile = "/var/lib/switchwayf/SProvider.metadata.conf.php"; + WAYFLogFile = "/var/log/switchwayf/wayf.log"; + #SWITCHWAYF_CONFIG = pkgs.writeText "switch_config.php" + # (builtins.readFile ./switch-config.php); + }; + }; +}