proxy-server.conf(5)
π proxy-server.conf(5) π
the OpenStack Swift proxy server configuration file β yes bestie, this is the one, the manual page, section 5, and we're about to read the whole thing together π«Ά
β¨ SYNOPSIS β¨
proxy-server.conf
πΈ DESCRIPTION πΈ
Okay so. This is the config file that the proxy server uses, and also the one that all the other proxy middlewares use. She's popular. She's booked and busy. π
The file follows the python-pastedeploy syntax. That means it's chopped up into sections, and each section is wrapped in square brackets [like this]. Inside each section you get a certain number of key/value parameters, and we're gonna go through all of them later in this page, no skipping, we do not skip here. π
Any line that starts with a # symbol? Ignored. Gone. Not invited. π«
If you want more tea on the python-pastedeploy config format, it's literally right here:
https://docs.pylonsproject.org/projects/pastedeploy/en/latest/#config-format
π GLOBAL SECTION π
This one is signalled by the section name [DEFAULT]. Here's everything that's allowed to live in there, bestie, one by one:
bind_ipβ the IP address the proxy server should bind to. Default is0.0.0.0, which means it binds to literally every available address. she's everywhere. πbind_portβ the TCP port the proxy server should bind to. Default is80.keep_idleβ the value to set for socketTCP_KEEPIDLE. Default value is600.bind_timeoutβ timeout for binding the socket. Default is30.backlogβ TCP backlog. That's the maximum number of allowed pending connections. Default value is4096.admin_keyβ the key used for admin calls that are HMAC signed. Default is empty, and empty means admin calls to/infoget disabled. π«disallowed_sectionsβ this one lets you withhold sections so they don't show up in the public calls to/info. You can withhold subsections too by separating the dict level with a".". The following would cause the sections'container_quotas'and'tempurl'to not be listed, and the keymax_failed_deleteswould be removed frombulk_delete. Default value is'swift.valid_api_versions', which allows all registered features to be listed via HTTPGET /infoβ except theswift.valid_api_versionsinformation. sneaky lil exception, love that for us. πworkersβ the number of pre-forked processes that will accept connections. Zero means no fork. The default isauto, which makes the server try to match the number of effective cpu cores if python multiprocessing is available (it's included with most python distributions>= 2.6), or fall back to one. And it's worth noting β fr fr β that individual workers will use many eventlet co-routines to service multiple concurrent requests. multitasking icon. β¨max_clientsβ the maximum number of clients one worker can process simultaneously (it will actuallyaccept(2)N + 1). Setting this to one (1) will only handle one request at a time, without accepting another request concurrently. The default is1024.userβ the system user that the proxy server will run as. The default isswift.expose_infoβ enables exposing configuration settings via HTTPGET /info. The default istrue.swift_dirβ the Swift configuration directory. The default is/etc/swift.cert_fileβ location of the SSL certificate file. Default path is/etc/swift/proxy.crt. This is disabled by default.key_fileβ location of the SSL certificate key file. Default path is/etc/swift/proxy.key. This is disabled by default.log_nameβ the label used when logging. The default isswift.log_facilityβ syslog log facility. The default isLOG_LOCAL0.log_levelβ logging level. The default isINFO.log_addressβ logging address. The default is/dev/log.log_max_line_lengthβ caps the length of log lines to whatever value you give it. No limit if set to0, which is the default.log_headersβ the default isfalse.log_custom_handlersβ a comma separated list of functions to call to set up custom log handlers. The functions get passed:conf,name,log_to_console,log_route,fmt,logger,adapted_logger. The default is empty.log_udp_hostβ if it's set,log_udp_hostwill overridelog_address. π₯log_udp_portβ UDP log port, the default is514.log_statsd_hostβ the StatsD server. IPv4/IPv6 addresses and hostnames are both supported. If a hostname resolves to both an IPv4 and an IPv6 address, the IPv4 address will be used.log_statsd_portβ the default is8125.log_statsd_default_sample_rateβ the default is1.log_statsd_sample_rate_factorβ the default is1.log_statsd_metric_prefixβ the default is empty.client_timeoutβ the time to wait while receiving each chunk of data from a client or another backend node. The default is60.eventlet_debugβ debug mode for the eventlet library. The default isfalse.trans_id_suffixβ this optional suffix (default is empty) gets appended to the swift transaction id, and it lets you easily figure out which cluster thatX-Trans-Idbelongs to. This is very useful when you're managing more than one swift cluster. chef's kiss for multi-cluster girlies. πcors_allow_originβ a list of origin hosts that are allowed for CORS requests, in addition to whatever the container has set. Use a comma separated list of full URL (http://foo.bar:1234,https://foo.bar).strict_cors_modeβ ifTrue(which is the default) then CORS requests are only allowed if theirOriginheader matches an allowed origin. Otherwise, any Origin is allowed. pick your lane bestie. π―cors_expose_headersβ a comma separated list of headers to expose throughAccess-Control-Expose-Headers, in addition to the defaults and any headers set in container metadata.nice_priorityβ modifies the scheduling priority of server processes. Niceness values range from-20(most favorable to the process) to19(least favorable to the process). The default does not modify priority.ionice_classβ modifies the I/O scheduling class of server processes. I/O niceness class values areIOPRIO_CLASS_RT(realtime),IOPRIO_CLASS_BE(best-effort) andIOPRIO_CLASS_IDLE(idle). The default does not modify class and priority. Work only withionice_priority.ionice_priorityβ modifies the I/O scheduling priority of server processes. I/O niceness priority is a number which goes from0to7. The higher the value, the lower the I/O priority of the process. Work only withionice_class. Ignored ifIOPRIO_CLASS_IDLEis set.
π¦ PIPELINE SECTION π¦
This one is signalled by the section name [pipeline:main]. Here's what's allowed in there:
pipelineβ you use this when you need to apply a number of filters. It's a list of filters, ended by an application. The normal pipeline is:
"catch_errors gatekeeper healthcheck proxy-logging cache container_sync bulk tempurl ratelimit tempauth container-quotas account-quotas slo dlo versioned_writes proxy-logging proxy-server"
Note: the doubleproxy-loggingin the pipeline is not a mistake. The left-mostproxy-loggingis there to log requests that were handled in middleware and never made it through to the right-most middleware (and proxy server). Double logging is prevented for normal requests. See proxy-logging docs. π
π FILTER SECTION π
Any section whose name is prefixed by "filter:" is a filter section. Filters are used to specify configuration parameters for specific swift middlewares. Below are the filters available and their respective acceptable parameters, and yes we are doing all of them. πΈ
[filter:healthcheck]
useβ entry point for paste.deploy for the healthcheck middleware. This is the reference to the installed python egg. This is normallyegg:swift#healthcheck.disable_pathβ an optional filesystem path which, if present, will cause the healthcheck URL to return"503 Service Unavailable"with a body of"DISABLED BY FILE". she said no π
[filter:tempauth]
useβ entry point for paste.deploy for the tempauth middleware. This is the reference to the installed python egg. This is normallyegg:swift#tempauth.set log_nameβ label used when logging. The default istempauth.set log_facilityβ syslog log facility. The default isLOG_LOCAL0.set log_levelβ logging level. The default isINFO.set log_addressβ logging address. The default is/dev/log.set log_headersβ enables the ability to log request headers. The default isFalse.reseller_prefixβ the reseller prefix will verify a token begins with this prefix before even attempting to validate it. Also, with authorization, only Swift storage accounts with this prefix will be authorized by this middleware. Useful if multiple auth systems are in use for one Swift cluster. The default isAUTH.auth_prefixβ the auth prefix will cause requests beginning with this prefix to be routed to the auth subsystem, for granting tokens, etc. The default is/auth/.require_groupβ therequire_groupparameter names a group that must be presented by eitherX-Auth-TokenorX-Service-Token. Usually this parameter is used only with multiple reseller prefixes (e.g.,SERVICE_require_group=blah). By default, no group is needed.
Do not use .admin. π«
token_lifeβ this is the time in seconds before the token expires. The default is86400.allow_overridesβ this allows middleware higher in the WSGI pipeline to override auth processing, useful for middleware such as tempurl and formpost. If you know you're not going to use such middleware and you want a bit of extra security, you can set this tofalse. The default istrue.storage_url_schemeβ this specifies what scheme to return with storage urls:http,https, ordefault(chooses based on what the server is running as). This can be useful with an SSL load balancer in front of a non-SSL server. balance that load bestie βοΈuser_<account>_<user>β lastly, you need to list all the accounts/users you want here. The format is:
user_<account>_<user> = <key> [group] [group] [...] [storage_url]
or if you want underscores in <account> or <user>, you can base64 encode them (with no equal signs) and use this format:
user64_<account_b64>_<user_b64> = <key> [group] [group] [...] [storage_url]
okay that's the end of part 1, but we are NOT done, there's more coming so stay tuned bestie π
Okay bestie, so there are these special little groups π: .reseller_admin β who can do literally anything to any account for this auth β and .admin, who can do anything but only within the account. Two tiers of power, very main character vs. supporting cast π
And if neither of those groups is specified? Then the user can only touch containers that a .admin or a .reseller_admin has explicitly allowed for them. No sneaky access, periodt π«β¨
That trailing optional storage_url? It lets you hand back an alternate URL to the user once they authenticate. If you don't specify it, it defaults to:
http[s]://<ip>:<port>/v1/<reseller_prefix>_<account>
β¦where http or https depends on whether cert_file is set in the [DEFAULT] section, <ip> and <port> come from the [DEFAULT] section's bind_ip and bind_port (and if those aren't there, they fall back to 127.0.0.1 and 8080 π), <reseller_prefix> is from this section, and <account> comes from the user_<account>_<user> name. iykyk π§
Here are the example entries, which are required for running the tests:
user_admin_admin = admin .admin .reseller_admin
user_test_tester = testing .admin
user_test2_tester2 = testing2 .admin
user_test_tester3 = testing3
β¨ [filter:authtoken] β¨
To turn on Keystone authentication, you need to have the auth token middleware configured first β order matters, bestie π. Here's an example below, and for all the different settings please go check Keystone's own documentation, okurrr?
You'll also need the keystoneauth middleware enabled and sitting in your main pipeline, so instead of having tempauth chilling in there, you can swap it to: authtoken keystoneauth π¦
The auth credentials ("project_domain_name","user_domain_name","username","project_name","password") must match the Keystone credentials for the Swift service. The example values shown here assume a user named"swift"with admin role on a project named"service", both of them living in the Keystone domain with id"default". For other examples, refer to the KeystoneMiddleware documentation athttps://docs.openstack.org/keystonemiddleware/latest/middlewarearchitecture.html#configurationπ
paste.filter_factory =
keystonemiddleware.auth_token:filter_factory
www_authenticate_uri = http://keystonehost:5000
auth_url = http://keystonehost:5000
auth_plugin = password
project_domain_id = default
user_domain_id = default
project_name = service
username = swift
password = password
# delay_auth_decision defaults to False, but leaving it as
false will
# prevent other auth systems, staticweb, tempurl, formpost,
and ACLs from
# working. This value must be explicitly set to True.
delay_auth_decision = False
cache = swift.cache
include_service_catalog = False
β¨ [filter:keystoneauth] β¨
Keystone authentication middleware. Your friendly neighborhood gatekeeper π₯
useβ Entry point for paste.deploy for the keystoneauth middleware. This is the reference to the installed python egg. This is normallyegg:swift#keystoneauth.reseller_prefixβ This option lists account namespaces that this middleware is responsible for. The prefix gets placed before the Keystone project id. So for project12345678with prefixAUTH, the account is namedAUTH_12345678(i.e., the path is/v1/AUTH_12345678/...). You can have several prefixes by giving a comma-separated list, like:"reseller_prefix = AUTH, SERVICE". The empty string indicates a single blank/empty prefix. And if you need an empty prefix inside a list of prefixes, a value of''(two single quote characters) indicates a blank/empty prefix. Except for that blank/empty prefix, an underscore ('_') character is appended to the value unless it's already there. πoperator_rolesβ The user must have at least one role named byoperator_roleson a project in order to create, delete and modify containers and objects, and to set and read privileged headers such as ACLs. If there are several reseller prefix items, you can prefix the parameter so it applies only to those accounts β for example the parameterSERVICE_operator_rolesapplies to the/v1/SERVICE_<project>path. If you omit the prefix, the option applies to all reseller prefix items. For the blank/empty prefix, prefix with''(and do not put an underscore after the two single quote characters) πreseller_admin_roleβ The reseller admin role has the ability to create and delete accounts. Big power, big responsibility πallow_overridesβ This allows middleware higher in the WSGI pipeline to override auth processing, which is useful for middleware such as tempurl and formpost. If you know you're not going to use such middleware and you want a bit of extra security, you can set this tofalseπservice_rolesβ If theservice_rolesparameter is present, anX-Service-Tokenmust be present in the request that, when validated, grants at least one role listed in the parameter. TheX-Service-Tokenmay be scoped to any project. If there are several reseller prefix items, you can prefix the parameter so it applies only to those accounts β for example the parameterSERVICE_service_rolesapplies to the/v1/SERVICE_<project>path. If you omit the prefix, the option applies to all reseller prefix items. For the blank/empty prefix, prefix with''(do not put underscore after the two single quote characters). By default, noservice_rolesare required. β¨default_domain_idβ For backwards compatibility, keystoneauth will match names in cross-tenant access control lists (ACLs) when both the requesting user and the tenant are in the default domain, i.e. the domain to which existing tenants are migrated. Thedefault_domain_idvalue configured here should be the same as the value used during migration of tenants to keystone domains. π§allow_names_in_aclsβ For a new installation, or an installation in which keystone projects may move between domains, you should disable backwards compatible name matching in ACLs by settingallow_names_in_aclstofalse:
β¨ [filter:cache] β¨
Caching middleware that manages caching in swift. It's the vibe-keeper of your data πΈ
useβ Entry point for paste.deploy for the memcache middleware. This is the reference to the installed python egg. This is normallyegg:swift#memcache.set log_nameβ Label used when logging. The default ismemcache.set log_facilityβ Syslog log facility. The default isLOG_LOCAL0.set log_levelβ Logging level. The default isINFO.set log_addressβ Logging address. The default is/dev/log.set log_headersβ Enables the ability to log request headers. The default isFalse.memcache_max_connectionsβ Sets the maximum number of connections to each memcached server per worker.memcache_serversβ If not set in the configuration file, the value formemcache_serverswill be read from/etc/swift/memcache.conf(seememcache.conf-sample) or, lacking that file, it will default to127.0.0.1:11211. You can specify multiple servers separated with commas, as in:10.1.2.3:11211,10.1.2.4:11211. (IPv6 addresses must follow rfc3986 section-3.2.2, i.e.[::1]:11211) π
β¨ [filter:ratelimit] β¨
Rate limits requests on both an Account and Container level. The limits are configurable, bestie β you're in charge π
useβ Entry point for paste.deploy for the ratelimit middleware. This is the reference to the installed python egg. This is normallyegg:swift#ratelimit.set log_nameβ Label used when logging. The default isratelimit.set log_facilityβ Syslog log facility. The default isLOG_LOCAL0.set log_levelβ Logging level. The default isINFO.set log_addressβ Logging address. The default is/dev/log.set log_headersβ Enables the ability to log request headers. The default isFalse.clock_accuracyβ This should represent how accurate the proxy servers' system clocks are with each other.1000means that all the proxies' clocks are accurate to each other within 1 millisecond. No ratelimit should be higher than the clock accuracy. The default is1000.max_sleep_time_secondsβ App will immediately return a498response if the necessary sleep time ever exceeds the givenmax_sleep_time_seconds. The default is60seconds.log_sleep_time_secondsβ To allow visibility into rate limiting, set this value >0and all sleeps greater than the number will be logged. If set to0means disabled. The default is0.rate_buffer_secondsβ Number of seconds the rate counter can drop and be allowed to catch up (at a faster than listed rate). A larger number will result in larger spikes in rate but better average accuracy. The default is5.account_ratelimitβ If set, will limitPUTandDELETErequests to/account_name/container_name. Number is in requests per second. If set to0means disabled. The default is0.container_ratelimit_sizeβ When set withcontainer_limit_x = r: for containers of sizex, limit requests per second tor. Will limitPUT,DELETE, andPOSTrequests to/a/c/o. The default is''.container_listing_ratelimit_sizeβ Similarly to the above container-level write limits, the following will limit containerGET(listing) requests. π
β¨ [filter:domain_remap] β¨
Middleware that translates container and account parts of a domain to path parameters that the proxy server understands. β¨
So like, container.account.storageurl/object gets translated to container.account.storageurl/path_root/account/container/object, and account.storageurl/path_root/container/object gets translated to account.storageurl/path_root/account/container/object π¦
useβ the paste.deploy entry point for thedomain_remapmiddleware. It's a reference to the installed python egg, and bestie, it's normallyegg:swift#domain_remap. β¨set log_nameβ the label used when logging. Default isdomain_remap.set log_facilityβ the syslog log facility. Default isLOG_LOCAL0.set log_levelβ the logging level. Default isINFO.set log_addressβ the logging address. Default is/dev/log.set log_headersβ turns on the ability to log request headers. Default isFalse.storage_domainβ the domain the middleware is gonna use. You can stack multiple domains here, just separate them with a comma.path_rootβ the path root value for the storage URL. Default isv1.reseller_prefixesβ okay so real talk, browsers can lowercase a host header π, so this checks that the reseller prefix on the account is the correct case. It does that by comparing the items in thereseller_prefixesconfig option to the prefix it actually found. If they match except for case, the item fromreseller_prefixesgets used instead of the found reseller prefix. When none of them match, the default reseller prefix is used. And when there's no default reseller prefix configured, any request with an account prefix that's not in that list just gets ignored by this middleware. Defaults to'AUTH'.default_reseller_prefixβ the default reseller prefix, used when none of the configuredreseller_prefixesmatch. When it's not set, no reseller prefix gets added.
π¦ [filter:catch_errors] π¦
useβ the paste.deploy entry point for thecatch_errorsmiddleware. Reference to the installed python egg, normallyegg:swift#catch_errors.set log_nameβ label used when logging. Default iscatch_errors.set log_facilityβ syslog log facility. Default isLOG_LOCAL0.set log_levelβ logging level. Default isINFO.set log_addressβ logging address. Default is/dev/log.set log_headersβ enables the ability to log request headers. Default isFalse.
πΈ [filter:cname_lookup] πΈ
Note: this middleware requires python-dnspython β no cap, you need it.
useβ the paste.deploy entry point for thecname_lookupmiddleware. Reference to the installed python egg, normallyegg:swift#cname_lookup.set log_nameβ label used when logging. Default iscname_lookup.set log_facilityβ syslog log facility. Default isLOG_LOCAL0.set log_levelβ logging level. Default isINFO.set log_addressβ logging address. Default is/dev/log.set log_headersβ enables the ability to log request headers. Default isFalse.storage_domainβ the domain the middleware is gonna use.lookup_depthβ how deep down the CNAME chain it should look for something that matches the storage domain. Default is1.nameserversβ specifies the nameservers used to do the CNAME resolution. If it's unset, the system configuration gets used. You can list multiple nameservers, comma-separated. Default is unset.
π [filter:staticweb] π
Note: put staticweb just after your auth filter(s) in the pipeline. Order matters, fr fr.
useβ the paste.deploy entry point for thestaticwebmiddleware. Reference to the installed python egg, normallyegg:swift#staticweb.set log_nameβ label used when logging. Default isstaticweb.set log_facilityβ syslog log facility. Default isLOG_LOCAL0.set log_levelβ logging level. Default isINFO.set log_addressβ logging address. Default is/dev/log.set log_headersβ enables the ability to log request headers. Default isFalse.
π
[filter:tempurl] π
Note: puttempurlbeforeslo,dlo, and your auth filter(s) in the pipeline. Do not skip this, bestie.
useβ the paste.deploy entry point for thetempurlmiddleware. Reference to the installed python egg, normallyegg:swift#tempurl.methodsβ the methods allowed with Temp URLs. Default is'GET HEAD PUT POST DELETE'.incoming_remove_headersβ the headers to remove from incoming requests. It's just a whitespace-delimited list of header names, and names can optionally end with'*'to indicate a prefix match.incoming_allow_headersis the list of exceptions to these removals.incoming_allow_headersβ the headers allowed as exceptions toincoming_remove_headers. Again, just a whitespace-delimited list of header names, and names can optionally end with'*'to mean a prefix match.outgoing_remove_headersβ the headers to remove from outgoing responses. Whitespace-delimited list of header names, names can optionally end with'*'for a prefix match.outgoing_allow_headersis the list of exceptions to these removals.outgoing_allow_headersβ the headers allowed as exceptions tooutgoing_remove_headers. Whitespace-delimited list of header names, names can optionally end with'*'for a prefix match.
π [filter:formpost] π
Note: put formpost just before your auth filter(s) in the pipeline.
useβ the paste.deploy entry point for theformpostmiddleware. Reference to the installed python egg, normallyegg:swift#formpost.
π§ [filter:name_check] π§
Note: it just needs to be placed before the proxy-server in the pipeline.
useβ the paste.deploy entry point for thename_checkmiddleware. Reference to the installed python egg, normallyegg:swift#name_check.forbidden_charsβ characters that will not be allowed in a name. The default is:
'"`<>
maximum_lengthβ the maximum number of characters that can be in the name. Default is255.forbidden_regexpβ Python regular expressions of substrings that will not be allowed in a name. Default is/./|/../|/.$|/..$/.
β [filter:list-endpoints] β
useβ the paste.deploy entry point for thelist_endpointsmiddleware. Reference to the installed python egg, normallyegg:swift#list_endpoints.list_endpoints_pathβ default is'/endpoints/'.
π [filter:proxy-logging] π
Logging for the proxy server now lives in this middleware, okay? And if the access_* variables aren't set, logging directives from [DEFAULT] without "access_" will be used. Slay.
useβ the paste.deploy entry point for theproxy_loggingmiddleware. Reference to the installed python egg, normallyegg:swift#proxy_logging.access_log_nameβ label used when logging. Default isproxy-server.access_log_facilityβ syslog log facility. Default isLOG_LOCAL0.access_log_levelβ logging level. Default isINFO.access_log_addressβ default is/dev/log.access_log_udp_hostβ if it's set,access_log_udp_hostoverridesaccess_log_address. Default is unset.access_log_udp_portβ default is514.access_log_statsd_hostβ you can uselog_statsd_*from[DEFAULT], or override them right here. It's the StatsD server. IPv4/IPv6 addresses and hostnames are supported. If a hostname resolves to both an IPv4 and an IPv6 address, the IPv4 address gets used.access_log_statsd_portβ default is8125.access_log_statsd_default_sample_rateβ default is1.access_log_statsd_sample_rate_factorβ default is1.access_log_statsd_metric_prefixβ default is""(empty-string).access_log_headersβ default isFalse.access_log_headers_onlyβ ifaccess_log_headersisTrueandaccess_log_headers_onlyis set, only these headers get logged. You can define multiple headers as a comma-separated list, like this:
access_log_headers_only = Host, X-Object-Meta-Mtime
reveal_sensitive_prefixβ by default, theX-Auth-Tokenis logged. To obscure the value, setreveal_sensitive_prefixto the number of characters to log. So like, if you set it to12, only the first 12 characters of the token show up in the log. That way an unauthorized peek at the log file won't let someone actually use the token π. But the first 12-ish characters is unique enough that you can still trace/debug token usage. Set it to0to suppress the token completely (it gets replaced by'...'in the log). Default is16chars.
Note:reveal_sensitive_prefixwill not affect the value logged withaccess_log_headers=True.
log_statsd_valid_http_methodsβ which HTTP methods are allowed for StatsD logging (comma-sep). Request methods not in this list get"BAD_METHOD"for the<verb>portion of the metric. Default is"GET,HEAD,POST,PUT,DELETE,COPY,OPTIONS".log_anonymization_methodβ the hashing algorithm for anonymization. It has to be one of the algorithms supported by Python'shashlib. Default isMD5.log_anonymization_saltβ salt added as a prefix before hashing the value to anonymize. Default is empty (no salt).log_msg_templateβ the template used to format access logs. All words surrounded by curly brackets get substituted with the appropriate values. π
Quick vibe check bestie π β some keywords are literally timestamps in disguise, and you can glow them up into proper date formats with their matching transformers:'datetime','asctime'or'iso8601'.
Other timestamp transformers that exist: 's', 'ms', 'us' and 'ns' β that's seconds, milliseconds, microseconds and nanoseconds, slay. β¨
You can also use Python's strftime directives as transformers, and the whole roster is: a, A, b, B, c, d, H, I, j, m, M, p, S, U, w, W, x, X, y, Y, Z. Periodt. π
And then some keywords map to user data that you can anonymize with the transformer 'anonymized'. Iconic.
Keywords available are:
client_ip(anonymizable)remote_addr(anonymizable)method(request method)path(anonymizable)protocolstatus_intreferer(anonymizable)user_agent(anonymizable)auth_tokenbytes_recvd(number of bytes received)bytes_sent(number of bytes sent)client_etag(anonymizable)transaction_idheaders(anonymizable)request_time(difference between start and end timestamps)sourcelog_infostart_time(timestamp at the receiving, timestamp)end_time(timestamp at the end of the treatment, timestamp)ttfb(duration between request and first bytes is sent)policy_indexaccount(account name, anonymizable)container(container name, anonymizable)object(object name, anonymizable)pid(PID of the process emitting the log line)
Example, and no I will not be normal about it:
'{client_ip.anonymized} {remote_addr.anonymized} {start_time.iso8601} {end_time.H}:{end_time.M} {method} acc:{account} cnt:{container} obj:{object.anonymized}'
Default:
'{client_ip} {remote_addr} {end_time.datetime} {method} {path} {protocol} {status_int} {referer} {user_agent} {auth_token} {bytes_recvd} {bytes_sent} {client_etag} {transaction_id} {headers} {request_time} {source} {log_info} {start_time} {end_time} {policy_index}'
Warning: a bad log message template will raise an error in initialization. π So like, don't freestyle it, bestie.
π§Ί [filter:bulk] π§Ί
Note: put this before bothratelimitandauthin the pipeline. The order matters, iykyk.
useβ entry point for paste.deploy for the bulk middleware. This is the reference to the installed python egg. Normally it'segg:swift#bulk.max_containers_per_extractionβ the default is10000.max_failed_extractionsβ the default is1000.max_deletes_per_requestβ the default is10000.max_failed_deletesβ the default is1000.yield_frequencyβ so here's the tea π«: to keep a connection active during a potentially long bulk request, Swift may return whitespace prepended to the actual response body. That whitespace will be yielded no more than everyyield_frequencyseconds. The default is10.delete_container_retry_countβ Note: this parameter is used during a bulk delete of objects and their container. This would frequently fail because it is very likely that all replicated objects have not been deleted by the time the middleware got a successful response. You can configure the number of retries. And the number of seconds to wait between each retry will be1.5**retry. The default is0.
βοΈ [filter:slo] βοΈ
Note: put this afterauthandstaticwebin the pipeline. β¨
useβ entry point for paste.deploy for the slo middleware. This is the reference to the installed python egg. Normally it'segg:swift#slo.max_manifest_segmentsβ the default is1000.max_manifest_sizeβ the default is2097152.min_segment_sizeβ the default is1048576.rate_limit_after_segmentβ start rate-limiting object segments after the Nth segment of a segmented object. The default is10segments.rate_limit_segments_per_secβ once segment rate-limiting kicks in for an object, limit segments served to N per second. The default is1.max_get_timeβ time limit onGETrequests (seconds). The default is86400.
π° [filter:dlo] π°
Note: put this afterauthandstaticwebin the pipeline. And heads up β if you don't put it in the pipeline, it will be inserted for you. πͺ
useβ entry point for paste.deploy for the dlo middleware. This is the reference to the installed python egg. Normally it'segg:swift#dlo.rate_limit_after_segmentβ start rate-limiting object segments after the Nth segment of a segmented object. The default is10segments.rate_limit_segments_per_secβ once segment rate-limiting kicks in for an object, limit segments served to N per second. The default is1.max_get_timeβ time limit onGETrequests (seconds). The default is86400.
π¦ [filter:container-quotas] π¦
Note: put this after auth in the pipeline.
useβ entry point for paste.deploy for thecontainer_quotasmiddleware. This is the reference to the installed python egg. Normally it'segg:swift#container_quotas.
ποΈ [filter:account-quotas] ποΈ
Note: put this after auth in the pipeline.
useβ entry point for paste.deploy for theaccount_quotasmiddleware. This is the reference to the installed python egg. Normally it'segg:swift#account_quotas.
πͺ [filter:gatekeeper] πͺ
Note: this middleware requires python-dnspython. Don't forget the dependency bestie, it's giving unfinished homework. π
useβ entry point for paste.deploy for the gatekeeper middleware. This is the reference to the installed python egg. Normally it'segg:swift#gatekeeper.set log_nameβ label used when logging. The default isgatekeeper.set log_facilityβ syslog log facility. The default isLOG_LOCAL0.set log_levelβ logging level. The default isINFO.set log_addressβ logging address. The default is/dev/log.set log_headersβ enables the ability to log request headers. The default isFalse.
π [filter:container_sync] π
Note: this middleware requires python-dnspython. Again. π«Ά
useβ entry point for paste.deploy for thecontainer_syncmiddleware. This is the reference to the installed python egg. Normally it'segg:swift#container_sync.allow_full_urlsβ set this tofalseif you want to disallow any full URL values to be set for any newX-Container-Sync-Toheaders. This will keep any new full urls from coming in, but won't change any existing values already in the cluster. Updating those will have to be done manually, as knowing what the true realm endpoint should be cannot always be guessed. The default istrue.currentβ set this to specify this cluster's//realm/clusteras"current"in/info.
π¬ [filter:xprofile] π¬
Note: put it at the beginning of the pipeline to profile all middleware. But it is safer to put this after healthcheck. Safety first, gorgeous. β¨
useβ entry point for paste.deploy for the xprofile middleware. This is the reference to the installed python egg. Normally it'segg:swift#xprofile.profile_moduleβ this option enable you to switch profilers which should inherit from python standard profiler. Currently the supported value can be'cProfile','eventlet.green.profile'etc.log_filename_prefixβ this prefix will be used to combine process ID and timestamp to name the profile data file. Make sure the executing user has permission to write into this path (missing path segments will be created, if necessary). If you enable profiling in more than one type of daemon, you must override it with an unique value like, the default is/var/log/swift/profile/account.profile.dump_intervalβ the profile data will be dumped to local disk based on above naming rule in this interval. The default is5.0.dump_timestampβ be careful, this option will enable profiler to dump data into the file with time stamp which means there will be lots of files piled up in the directory. The default isfalse.pathβ this is the path of the URL to access the mini web UI. The default is__profile__.flush_at_shutdownβ clear the data when the wsgi server shutdown. The default isfalse.unwindβ unwind the iterator of applications. Default isfalse.
π [filter:versioned_writes] π
Note: put this afterslo,dloin the pipeline. If you don't put it in the pipeline, it will be inserted automatically. πͺ
useβ entry point for paste.deploy for theversioned_writesmiddleware. This is the reference to the installed python egg. Normally it'segg:swift#versioned_writes.allow_versioned_writesβ enables using versioned writes middleware and exposing configuration settings via HTTPGET /info.
WARNING: setting this option bypasses the "allow_versions" option in the container configuration file, which will be eventually deprecated. See documentation for more details. π
β¨ APP SECTION β¨
This one's flagged by the section name [app:proxy-server]. Below are all the parameters that are allowed to live in here, bestie. π
useβ the entry point forpaste.deployfor the proxy server. It's a reference to the installed python egg. Normally it'segg:swift#proxy. π₯set log_nameβ the label used when logging. Default isproxy-server.set log_facilityβ syslog log facility. Default isLOG_LOCAL0.set log_levelβ logging level. Default isINFO.set log_addressβ logging address. Default is/dev/log.log_handoffsβ logs when handoff locations get used. Default isTrue. πrecheck_account_existenceβ cache timeout in seconds to send memcached for account existence. Default is60seconds.recheck_container_existenceβ cache timeout in seconds to send memcached for container existence. Default is60seconds.object_chunk_sizeβ chunk size to read from object servers. Default is65536.client_chunk_sizeβ chunk size to read from clients. Default is65536.node_timeoutβ request timeout to external services. Default is10seconds.recoverable_node_timeoutβ how long the proxy server will wait for an initial response and to read a chunk of data from the object servers while serving GET / HEAD requests. Timeouts from these requests can be recovered from, so setting this lower thannode_timeoutgives you quicker error recovery while still allowing a longer timeout for the non-recoverable requests (PUTs). Defaults tonode_timeout, and you should override it ifnode_timeoutis set to a high number β otherwise client timeouts can fire before the proxy server even gets a chance to retry. πconn_timeoutβ connection timeout to external services. Default is0.5seconds.post_quorum_timeoutβ how long to wait for requests to finish after a quorum has been established. Default is0.5seconds.error_suppression_intervalβ time in seconds that must elapse since the last error for a node to be considered no longer error limited. Default is60seconds.error_suppression_limitβ error count to consider a node error limited. Default is10.allow_account_managementβ whether account PUTs and DELETEs are even callable at all. Set to'true'and any authorized user may create and delete accounts; set to'false'and nobody can, not even authorized users. Default isfalse.account_autocreateβ set to'true'and authorized accounts that don't exist yet within the Swift cluster get automatically created. Default is set tofalse.max_containers_per_accountβ set to a positive value, and trying to create a container when the account already has at least this many containers results in a403 Forbidden. Note: this is a soft limit, meaning a user might exceed the cap forrecheck_account_existencebefore the 403s kick in. πmax_containers_whitelistβ a comma separated list of account hashes that ignore themax_containers_per_accountcap.deny_host_headersβ comma separated list of Host headers to which the proxy will deny requests. Default is empty.sorting_methodβ storage nodes can be chosen at random (shuffleβ the default), by using timing measurements (timing), or by using an explicit match (affinity). Using timing measurements may allow for lower overall latency, while using affinity allows for finer control. In both the timing and affinity cases, equally-sorting nodes are still randomly chosen to spread load. The valid values forsorting_methodare"affinity","shuffle", and"timing". π―timing_expiryβ if the"timing"sorting_methodis used, the timings will only be valid for the number of seconds configured bytiming_expiry. Default is300.concurrent_getsβ if"on", then use replica count number of threads concurrently during a GET/HEAD and return with the first successful response. In the EC case, this parameter only affects an EC HEAD, since an EC GET behaves differently. Default is"off".concurrency_timeoutβ controls how long to wait before firing off the nextconcurrent_getthread. A value of0would be fully concurrent; any other number will stagger the firing of the threads. This number should be between0andnode_timeout. Default is the value ofconn_timeout(0.5).request_node_countβ set to the number of nodes to contact for a normal request. You can use'* replicas'at the end to have it use the number given times the number of replicas for the ring being used for the request. Default is'2 * replicas'.read_affinityβ specifies which backend servers to prefer on reads. The format is a comma separated list of affinity descriptors of the form<selection>=<priority>. The<selection>may ber<N>for selecting nodes in region N, orr<N>z<M>for selecting nodes in region N, zone M. The<priority>value should be a whole number representing the priority given to the selection; lower numbers are higher priority. Default is empty, meaning no preference. π
Example: first read from region 1 zone 1, then region 1 zone 2, then anything in region 2, then everything else:
read_affinity = r1z1=100, r1z2=200, r2=300
write_affinityβ specifies which backend servers to prefer on writes. The format is a comma separated list of affinity descriptors of the formr<N>for region N, orr<N>z<M>for region N, zone M. If this is set, then when handling an object PUT request, some number (see thewrite_affinity_node_countsetting) of local backend servers will be tried before any nonlocal ones. Default is empty, meaning no preference.
Example: try to write to regions 1 and 2 before writing to any other nodes:
write_affinity = r1, r2
write_affinity_node_countβ the number of local (as governed by thewrite_affinitysetting) nodes to attempt to contact first on writes, before any non-local ones. The value should be an integer number, or use'* replicas'at the end to have it use the number given times the number of replicas for the ring being used for the request. Default is'2 * replicas'.swift_owner_headersβ these are the headers whose values will only be shown to swift_owners. The exact definition of a swift_owner is up to the auth system in use, but usually it indicates administrative responsibilities. The default is'x-container-read, x-container-write, x-container-sync-key, x-container-sync-to, x-account-meta-temp-url-key, x-account-meta-temp-url-key-2, x-container-meta-temp-url-key, x-container-meta-temp-url-key-2, x-account-access-control'. πrate_limit_after_segmentβ start rate-limiting object segments after the Nth segment of a segmented object. Default is10segments.rate_limit_segments_per_secβ once segment rate-limiting kicks in for an object, limit segments served to N per second. Default is1.nice_priorityβ modify scheduling priority of server processes. Niceness values range from-20(most favorable to the process) to19(least favorable to the process). The default does not modify priority.ionice_classβ modify I/O scheduling class of server processes. I/O niceness class values areIOPRIO_CLASS_RT(realtime),IOPRIO_CLASS_BE(best-effort) andIOPRIO_CLASS_IDLE(idle). The default does not modify class and priority. Works only withionice_priority.ionice_priorityβ modify I/O scheduling priority of server processes. I/O niceness priority is a number which goes from0to7. The higher the value, the lower the I/O priority of the process. Works only withionice_class. Ignored ifIOPRIO_CLASS_IDLEis set.
π DOCUMENTATION π
More in depth documentation about the swift-proxy-server and also OpenStack Swift as a whole can be found at https://docs.openstack.org/swift/latest/admin_guide.html and https://docs.openstack.org/swift/latest/. Go read it, bestie, it's giving β¨ knowledge β¨
π SEE ALSO π
and that's the whole page, we did it!! π no cap, you now know proxy-server.conf(5) better than like 90% of the internet.
source: Linux Β· version/date: 8/26/2011 Β· page: proxy-server.conf(5)
ily, go slay your config ππ¦β¨
π¦ where this page comes from
- debian trixie: swift-proxy 2.35.1-0+deb13u3 Β· Apache-2
- debian trixie: swift-proxy 2.35.1-0+deb13u4 Β· Apache-2
- nixos 26.05: python3.13-swift 2.37.1
- nixos 26.05: python3.14-swift 2.37.1
- nixpkgs unstable: python3.13-swift 2.38.3
- nixpkgs unstable: python3.14-swift 2.38.3
- ubuntu questing: swift-proxy 2.36.0-0ubuntu1
- ubuntu questing: swift-proxy 2.36.0-0ubuntu1.1
- ubuntu resolute: swift-proxy 2.37.1-0ubuntu2 Β· Apache-2
- ubuntu resolute: swift-proxy 2.37.1-0ubuntu2.1 Β· Apache-2
- ubuntu stonking: swift-proxy 2.38.2-0ubuntu1 Β· Apache-2
- Copyright (c) 2010-2012 OpenStack Foundation
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms