ACL using current system date or time?

Is it possible to create an ACL to query the current date inside haproxy.conf ?

For example, I may want to limit access to a backend server depending on date and/or time. I can see date specific ACLs useful for vacation booking sites or protected services like an SSH passthrough limiting logins to specific times of the day.

The following haproxy.conf example is using a static date string as a proof of concept looking for the 15th day of the month. This date string format was taken from the haproxy local time “%Tl” log variable. Is there another function like “date()” that can be queried?

frontend tcp_director
  mode tcp
  option tcplog
  bind 127.0.0.1:443
  default_backend server-01
  #
  # Allow access only on the 15th of the month , %Tl string
  acl date_allow str("15/May/2021:14:00:44 -0400") -m beg "15/"
  use_backend server-15 if date_allow

Thanks for your time. Ideas and insights are welcome.

hello @Amaterasu

you can use the date sample fetch method
https://cbonte.github.io/haproxy-dconv/2.0/configuration.html#7.3.2-date

acl not_before date gt 1622491790
acl not_after  date lt 1622491800
use_backend server-15 if not_before not_after

Adjust the timestamps to your liking

1 Like

@Gabrieltz , thank you for the example. We also found another configuration and wanted to share.

Special thanks to the site, calomel.org for proposing alternate solutions and explaining the following examples.

TLDR: use date,ltime() to query the system date / local time, convert the unix time integer to a date formatted string and define a named string variable with the directive, set-var .

Example 1: Query the current system date and set the two(2) digit day value to the string variable req.renew_date . The day variable “%d” is 01 through 31 . Requests going to the hostname booking.example.com and only on the 15th of the month will use the backend vacation_server.

frontend tcp_director
  mode tcp
  option tcplog
  bind 127.0.0.1:443
  default_backend server_cluster
  #
  # Vacation Booking, limit access to the 15th of the month and by specific hostname
  tcp-request content set-var(req.renew_date) date,ltime(%d)
  acl booking_date var(req.renew_date) eq 15
  acl booking_sni req.ssl_sni booking.example.com
  use_backend vacation_server if booking_date booking_sni

Example 2: Query the current system date and the hour setting the variable req.renew_date . The day “%d” is 01 through 31 and the hour “%H” is 00 though 23 . All requests between the local times of 8:00am and 8:59am and only on the 15th of the month will use the backend vacation_server.

frontend tcp_director
  mode tcp
  option tcplog
  bind 127.0.0.1:443
  default_backend server_cluster
  #
  # Vacation Booking, limit access to 8am-9am on the 15th day of the month 
  tcp-request content set-var(req.renew_date) date,ltime(%d%H)
  acl booking_date var(req.renew_date) eq 1508
  use_backend vacation_server if booking_date

Example 3: Any request, including an ssh tunneled connection through https can be limited by time of the day. Query the current system hour “%H” which results in the strings 00 though 23 set to the variable req.ssh_hour. New ssh-through-https requests going to the hostname ssh.example.com during the hours 09 through 16 (9am through 4:59pm local time) use the backend service_ssh.

frontend tcp_director
  mode tcp
  option tcplog
  bind 127.0.0.1:443
  default_backend server_cluster
  #
  # ssh through https tunnel, limit access between 09am-5pm local time to specific hostname
  tcp-request content set-var(req.ssh_hour) date,ltime(%H)
  acl ssh_hour var(req.ssh_hour) eq 09 || 10 || 11 || 12 || 13 || 14 || 15 || 16
  acl ssh_sni req.ssl_sni ssh.example.com
  use_backend service_ssh if ssh_hour ssh_sni

Hope this helps.

3 Likes

sorry if is too late for ask , this solution work i modified to use http request… so i need some similar but to the day of the week based acl.
i set
http-request set-var(req.day_week) date,ltime(%u) test with %w , in uppercase not is day of the week…

http-request set-var(req.day_week) date,ltime(%u)
acl ssh_hour var(req.day_week) eq 01 || 02 || 03 || 04 || 05 

to define mon-fri day of the week based acl but no success

Thanks’ @enriluis for your add but after some tries it appears that week days don’t have “0”. So the right syntax is :

acl ssh_hour date,ltime(%u) eq 1 || 2 || 3 || 4 || 5

Hope this helps