From 9628f1ba16d6eaa92bf2f25afafcf7539469885f Mon Sep 17 00:00:00 2001 From: Paul Caskey Date: Sat, 22 Feb 2020 15:28:32 +0000 Subject: [PATCH] UETN recommendations --- Dockerfile | 34 ++- Jenkinsfile | 3 +- .../docker-entrypoint.sh | 0 test-compose/db/Dockerfile | 49 ++++ .../db/container_files/rad-schema.sql | 150 ++++++++++ test-compose/docker-compose.yml | 48 ++++ test-compose/radius/Dockerfile | 6 + .../radius/container_files/rad-sql.cfg | 266 ++++++++++++++++++ 8 files changed, 547 insertions(+), 9 deletions(-) rename docker-entrypoint.sh => container_files/docker-entrypoint.sh (100%) create mode 100644 test-compose/db/Dockerfile create mode 100644 test-compose/db/container_files/rad-schema.sql create mode 100644 test-compose/docker-compose.yml create mode 100644 test-compose/radius/Dockerfile create mode 100644 test-compose/radius/container_files/rad-sql.cfg diff --git a/Dockerfile b/Dockerfile index 4bc8afd..2d4d142 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,34 @@ -ARG from=centos:centos7 -FROM ${from} +FROM centos:centos8 -RUN yum install -y openssl freeradius freeradius-mysql freeradius-utils php-common php-gd php-curl php-mysql mysql-server php-db mysql-client -RUN yum install -y apache2 libapache2-mod-php php-mail php-mime php-pear +RUN dnf install -y @freeradius freeradius-utils freeradius-mysql +RUN ln -s /etc/raddb/mods-available/sql /etc/raddb/mods-enabled/ +RUN chgrp -h radiusd /etc/raddb/mods-enabled/sql -# EPEL repository for freetds and hiredis -RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm +#RUN sed -i 's/\"rlm_sql_null\"/\"rlm_sql_mysql\"/' /etc/raddb/mods-available/sql \ +#&& sed -i 's/\"sqlite\"/\"mysql\"/' /etc/raddb/mods-available/sql \ +#&& sed -i '/server = \"localhost\"/s/^#*//g' /etc/raddb/mods-available/sql \ +#&& sed -i 's/\"localhost\"/\"${DB_HOST}\"/' /etc/raddb/mods-available/sql \ +#&& sed -i '/port = \"3306\"/s/^#*//g' /etc/raddb/mods-available/sql \ +#&& sed -i 's/\"3306\"/\"${DB_PORT}\"/' /etc/raddb/mods-available/sql \ +#&& sed -i '/login = \"radius\"/s/^#*//g' /etc/raddb/mods-available/sql \ +#&& sed -i 's/login = \"radius\"/login = \"${DB_USER}\"/' /etc/raddb/mods-available/sql \ +#&& sed -i '/password = \"SuperStrongPassword\"/s/^#*//g' /etc/raddb/mods-available/sql \ +#&& sed -i 's/\"SuperStrongPassword\"/\"${DB_PWD}\"/' /etc/raddb/mods-available/sql \ +#&& sed -i 's/radius_db = \"radius\"/radius_db = \"${DB_NAME}\"/' /etc/raddb/mods-available/sql -COPY docker-entrypoint.sh / +#RUN cat /etc/raddb/mods-available/sql + + +#install httpd and php + + + +#install Daloradius + + +COPY container_files/docker-entrypoint.sh / +RUN chmod 755 /docker-entrypoint.sh EXPOSE 1812/udp 1813/udp ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/Jenkinsfile b/Jenkinsfile index 5b62dc1..1d39584 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -49,7 +49,7 @@ pipeline { script { try{ docker.withRegistry('https://registry.hub.docker.com/', "dockerhub-$maintainer") { - baseImg = docker.build("$maintainer/$imagename", "--build-arg GROUPER_CONTAINER_VERSION=$tag --no-cache .") + baseImg = docker.build("$maintainer/$imagename", "--no-cache .") } } catch(error) { def error_details = readFile('./debug'); @@ -103,6 +103,5 @@ def handleError(String message){ echo "${message}" currentBuild.setResult("FAILED") slackSend color: 'danger', message: "${message}" - //step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: 'chubing@internet2.edu', sendToIndividuals: true]) sh 'exit 1' } diff --git a/docker-entrypoint.sh b/container_files/docker-entrypoint.sh similarity index 100% rename from docker-entrypoint.sh rename to container_files/docker-entrypoint.sh diff --git a/test-compose/db/Dockerfile b/test-compose/db/Dockerfile new file mode 100644 index 0000000..0b20eb9 --- /dev/null +++ b/test-compose/db/Dockerfile @@ -0,0 +1,49 @@ +FROM centos:centos8 + +ARG DB_ROOT_PWD=SecretPassword +ENV DB_ROOT_PWD=$DB_ROOT_PWD + +ARG DB_USER=radius +ENV DB_USER=$DB_USER + +ARG DB_USER_PWD=password +ENV DB_USER_PWD=$DB_USER_PWD + +ARG DB_NAME=radius +ENV DB_NAME=$DB_NAME + +RUN dnf module install -y mariadb + +COPY container_files/rad-schema.sql / + +RUN mysql_install_db \ + && chown -R mysql:mysql /var/lib/mysql/ \ + && sed -i 's/^\(bind-address\s.*\)/# \1/' /etc/my.cnf \ + && sed -i 's/^\(log_error\s.*\)/# \1/' /etc/my.cnf \ + && sed -i 's/\[mysqld\]/\[mysqld\]\ncharacter_set_server = utf8/' /etc/my.cnf \ + && sed -i 's/\[mysqld\]/\[mysqld\]\ncollation_server = utf8_general_ci/' /etc/my.cnf \ + && sed -i 's/\[mysqld\]/\[mysqld\]\nport = 3306/' /etc/my.cnf \ + && cat /etc/my.cnf \ + && echo "/usr/bin/mysqld_safe &" > /tmp/config \ + && echo "mysqladmin --silent --wait=30 ping || exit 1" >> /tmp/config \ + #steps performed by mysql_secure_installation + && echo "mysql -e 'UPDATE mysql.user SET Password=PASSWORD(\"${DB_ROOT_PWD}\") WHERE User=\"root\";'" >> /tmp/config \ + && echo "mysql -e 'DELETE FROM mysql.user WHERE User=\"\";'" >> /tmp/config \ + && echo "mysql -e 'DELETE FROM mysql.user WHERE User=\"root\" AND Host NOT IN (\"localhost\", \"127.0.0.1\", \"::1\");'" >> /tmp/config \ + && echo "mysql -e 'DROP DATABASE IF EXISTS test;'" >> /tmp/config \ + && echo "mysql -e 'DELETE FROM mysql.db WHERE Db=\"test\" OR Db=\"test\\_%\";'" >> /tmp/config \ + && echo "mysql -e 'CREATE DATABASE ${DB_NAME};'" >> /tmp/config \ + && echo "mysql -e 'GRANT ALL ON ${DB_NAME}.* TO ${DB_USER}@localhost IDENTIFIED BY \"${DB_USER_PWD}\";'" >> /tmp/config \ + && echo "mysql -e 'FLUSH PRIVILEGES;'" >> /tmp/config \ + && echo "mysql -u root --password=${DB_PWD} radius < /rad-schema.sql" >> /tmp/config \ + && bash /tmp/config \ + && rm -f /tmp/config + + +#RUN (mysqld_safe & ) \ +# && while ! curl -s localhost:3306 > /dev/null; do echo waiting for mysqld to start; sleep 1; done; \ +# bin/gsh -registry -check -runscript -noprompt + +EXPOSE 3306 + +CMD mysqld_safe diff --git a/test-compose/db/container_files/rad-schema.sql b/test-compose/db/container_files/rad-schema.sql new file mode 100644 index 0000000..2de3666 --- /dev/null +++ b/test-compose/db/container_files/rad-schema.sql @@ -0,0 +1,150 @@ +########################################################################### +# $Id: 1059b115282ea738353fe4fbc8d92b03a338f8c1 $ # +# # +# schema.sql rlm_sql - FreeRADIUS SQL Module # +# # +# Database schema for MySQL rlm_sql module # +# # +# To load: # +# mysql -uroot -prootpass radius < schema.sql # +# # +# Mike Machado # +########################################################################### +# +# Table structure for table 'radacct' +# + +CREATE TABLE radacct ( + radacctid bigint(21) NOT NULL auto_increment, + acctsessionid varchar(64) NOT NULL default '', + acctuniqueid varchar(32) NOT NULL default '', + username varchar(64) NOT NULL default '', + realm varchar(64) default '', + nasipaddress varchar(15) NOT NULL default '', + nasportid varchar(15) default NULL, + nasporttype varchar(32) default NULL, + acctstarttime datetime NULL default NULL, + acctupdatetime datetime NULL default NULL, + acctstoptime datetime NULL default NULL, + acctinterval int(12) default NULL, + acctsessiontime int(12) unsigned default NULL, + acctauthentic varchar(32) default NULL, + connectinfo_start varchar(50) default NULL, + connectinfo_stop varchar(50) default NULL, + acctinputoctets bigint(20) default NULL, + acctoutputoctets bigint(20) default NULL, + calledstationid varchar(50) NOT NULL default '', + callingstationid varchar(50) NOT NULL default '', + acctterminatecause varchar(32) NOT NULL default '', + servicetype varchar(32) default NULL, + framedprotocol varchar(32) default NULL, + framedipaddress varchar(15) NOT NULL default '', + PRIMARY KEY (radacctid), + UNIQUE KEY acctuniqueid (acctuniqueid), + KEY username (username), + KEY framedipaddress (framedipaddress), + KEY acctsessionid (acctsessionid), + KEY acctsessiontime (acctsessiontime), + KEY acctstarttime (acctstarttime), + KEY acctinterval (acctinterval), + KEY acctstoptime (acctstoptime), + KEY nasipaddress (nasipaddress) +) ENGINE = INNODB; + +# +# Table structure for table 'radcheck' +# + +CREATE TABLE radcheck ( + id int(11) unsigned NOT NULL auto_increment, + username varchar(64) NOT NULL default '', + attribute varchar(64) NOT NULL default '', + op char(2) NOT NULL DEFAULT '==', + value varchar(253) NOT NULL default '', + PRIMARY KEY (id), + KEY username (username(32)) +); + +# +# Table structure for table 'radgroupcheck' +# + +CREATE TABLE radgroupcheck ( + id int(11) unsigned NOT NULL auto_increment, + groupname varchar(64) NOT NULL default '', + attribute varchar(64) NOT NULL default '', + op char(2) NOT NULL DEFAULT '==', + value varchar(253) NOT NULL default '', + PRIMARY KEY (id), + KEY groupname (groupname(32)) +); + +# +# Table structure for table 'radgroupreply' +# + +CREATE TABLE radgroupreply ( + id int(11) unsigned NOT NULL auto_increment, + groupname varchar(64) NOT NULL default '', + attribute varchar(64) NOT NULL default '', + op char(2) NOT NULL DEFAULT '=', + value varchar(253) NOT NULL default '', + PRIMARY KEY (id), + KEY groupname (groupname(32)) +); + +# +# Table structure for table 'radreply' +# + +CREATE TABLE radreply ( + id int(11) unsigned NOT NULL auto_increment, + username varchar(64) NOT NULL default '', + attribute varchar(64) NOT NULL default '', + op char(2) NOT NULL DEFAULT '=', + value varchar(253) NOT NULL default '', + PRIMARY KEY (id), + KEY username (username(32)) +); + + +# +# Table structure for table 'radusergroup' +# + +CREATE TABLE radusergroup ( + username varchar(64) NOT NULL default '', + groupname varchar(64) NOT NULL default '', + priority int(11) NOT NULL default '1', + KEY username (username(32)) +); + +# +# Table structure for table 'radpostauth' +# +CREATE TABLE radpostauth ( + id int(11) NOT NULL auto_increment, + username varchar(64) NOT NULL default '', + pass varchar(64) NOT NULL default '', + reply varchar(32) NOT NULL default '', + authdate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = INNODB; + +# +# Table structure for table 'nas' +# +CREATE TABLE nas ( + id int(10) NOT NULL auto_increment, + nasname varchar(128) NOT NULL, + shortname varchar(32), + type varchar(30) DEFAULT 'other', + ports int(5), + secret varchar(60) DEFAULT 'secret' NOT NULL, + server varchar(64), + community varchar(50), + description varchar(200) DEFAULT 'RADIUS Client', + PRIMARY KEY (id), + KEY nasname (nasname) +); + diff --git a/test-compose/docker-compose.yml b/test-compose/docker-compose.yml new file mode 100644 index 0000000..792cb50 --- /dev/null +++ b/test-compose/docker-compose.yml @@ -0,0 +1,48 @@ + +version: "3.3" + +services: + radius: + build: + context: ./radius/ + depends_on: + - db + expose: + - "1812/udp" + - "1813/udp" + - "443" + networks: + - front + - back + ports: + - "1812/udp:1812/udp" + - "1813/udp:1813/udp" + - "443:443" + + db: + build: + context: ./db/ + args: + DB_USER: radius + DB_USER_PWD: MySecretPassword + DB_ROOT_PWD: MySecretPassword + DB_NAME: radius + expose: + - "3306" + networks: + - back + ports: + - "3306:3306" + volumes: + - radius_db:/var/lib/mysql + + front: + driver: bridge + back: + driver: bridge + + +volumes: + radius_db: + driver: local + diff --git a/test-compose/radius/Dockerfile b/test-compose/radius/Dockerfile new file mode 100644 index 0000000..2429d89 --- /dev/null +++ b/test-compose/radius/Dockerfile @@ -0,0 +1,6 @@ +FROM tier/eduroam-radius:3.0_20200221 + + +COPY container_files/rad-sql.cfg /etc/raddb/mods-available/sql + + diff --git a/test-compose/radius/container_files/rad-sql.cfg b/test-compose/radius/container_files/rad-sql.cfg new file mode 100644 index 0000000..bc46c34 --- /dev/null +++ b/test-compose/radius/container_files/rad-sql.cfg @@ -0,0 +1,266 @@ +# -*- text -*- +## +## sql.conf -- SQL modules +## +## $Id: 4a59483c35c77f573fb177919e19ba4434cc3da1 $ + +###################################################################### +# +# Configuration for the SQL module +# +# The database schemas and queries are located in subdirectories: +# +# sql//main/schema.sql Schema +# sql//main/queries.conf Authorisation and Accounting queries +# +# Where "DB" is mysql, mssql, oracle, or postgresql. +# +# + +sql { + # The sub-module to use to execute queries. This should match + # the database you're attempting to connect to. + # + # * rlm_sql_mysql + # * rlm_sql_mssql + # * rlm_sql_oracle + # * rlm_sql_postgresql + # * rlm_sql_sqlite + # * rlm_sql_null (log queries to disk) + # + driver = "rlm_sql_mysql" + +# +# Several drivers accept specific options, to set them, a +# config section with the the name as the driver should be added +# to the sql instance. +# +# Driver specific options are: +# +# sqlite { +# # Path to the sqlite database +# filename = "/tmp/freeradius.db" +# +# # How long to wait for write locks on the database to be +# # released (in ms) before giving up. +# busy_timeout = 200 +# +# # If the file above does not exist and bootstrap is set +# # a new database file will be created, and the SQL statements +# # contained within the bootstrap file will be executed. +# bootstrap = "${modconfdir}/${..:name}/main/sqlite/schema.sql" +# } +# +# mysql { +# # If any of the files below are set, TLS encryption is enabled +# tls { +# ca_file = "/etc/ssl/certs/my_ca.crt" +# ca_path = "/etc/ssl/certs/" +# certificate_file = "/etc/ssl/certs/private/client.crt" +# private_key_file = "/etc/ssl/certs/private/client.key" +# cipher = "DHE-RSA-AES256-SHA:AES128-SHA" +# } +# +# # If yes, (or auto and libmysqlclient reports warnings are +# # available), will retrieve and log additional warnings from +# # the server if an error has occured. Defaults to 'auto' +# warnings = auto +# } +# +# postgresql { +# +# # unlike MySQL, which has a tls{} connection configuration, postgresql +# # uses its connection parameters - see the radius_db option below in +# # this file +# +# # Send application_name to the postgres server +# # Only supported in PG 9.0 and greater. Defaults to no. +# send_application_name = yes +# } +# + + # The dialect of SQL you want to use, this should usually match + # the driver you selected above. + # + # If you're using rlm_sql_null, then it should be the type of + # database the logged queries are going to be executed against. + dialect = "mysql" + + # Connection info: + # + server = "localhost" + port = 3306 + login = "radius" + password = "MySecretPassword" + + # Database table configuration for everything except Oracle + radius_db = "radius" + + # If you are using Oracle then use this instead +# radius_db = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SID=your_sid)))" + + # If you're using postgresql this can also be used instead of the connection info parameters +# radius_db = "dbname=radius host=localhost user=radius password=raddpass" + + # Postgreql doesn't take tls{} options in its module config like mysql does - if you want to + # use SSL connections then use this form of connection info parameter +# radius_db = "host=localhost port=5432 dbname=radius user=radius password=raddpass sslmode=verify-full sslcert=/etc/ssl/client.crt sslkey=/etc/ssl/client.key sslrootcert=/etc/ssl/ca.crt" + + # If you want both stop and start records logged to the + # same SQL table, leave this as is. If you want them in + # different tables, put the start table in acct_table1 + # and stop table in acct_table2 + acct_table1 = "radacct" + acct_table2 = "radacct" + + # Allow for storing data after authentication + postauth_table = "radpostauth" + + # Tables containing 'check' items + authcheck_table = "radcheck" + groupcheck_table = "radgroupcheck" + + # Tables containing 'reply' items + authreply_table = "radreply" + groupreply_table = "radgroupreply" + + # Table to keep group info + usergroup_table = "radusergroup" + + # If set to 'yes' (default) we read the group tables unless Fall-Through = no in the reply table. + # If set to 'no' we do not read the group tables unless Fall-Through = yes in the reply table. +# read_groups = yes + + # If set to 'yes' (default) we read profiles unless Fall-Through = no in the groupreply table. + # If set to 'no' we do not read profiles unless Fall-Through = yes in the groupreply table. +# read_profiles = yes + + # Remove stale session if checkrad does not see a double login + delete_stale_sessions = yes + + # Write SQL queries to a logfile. This is potentially useful for tracing + # issues with authorization queries. See also "logfile" directives in + # mods-config/sql/main/*/queries.conf. You can enable per-section logging + # by enabling "logfile" there, or global logging by enabling "logfile" here. + # + # Per-section logging can be disabled by setting "logfile = ''" +# logfile = ${logdir}/sqllog.sql + + # Set the maximum query duration and connection timeout + # for rlm_sql_mysql. +# query_timeout = 5 + + # As of version 3.0, the "pool" section has replaced the + # following configuration items: + # + # num_sql_socks + # connect_failure_retry_delay + # lifetime + # max_queries + + # + # The connection pool is new for 3.0, and will be used in many + # modules, for all kinds of connection-related activity. + # + # When the server is not threaded, the connection pool + # limits are ignored, and only one connection is used. + # + # If you want to have multiple SQL modules re-use the same + # connection pool, use "pool = name" instead of a "pool" + # section. e.g. + # + # sql1 { + # ... + # pool { + # ... + # } + # } + # + # # sql2 will use the connection pool from sql1 + # sql2 { + # ... + # pool = sql1 + # } + # + pool { + # Connections to create during module instantiation. + # If the server cannot create specified number of + # connections during instantiation it will exit. + # Set to 0 to allow the server to start without the + # database being available. + start = ${thread[pool].start_servers} + + # Minimum number of connections to keep open + min = ${thread[pool].min_spare_servers} + + # Maximum number of connections + # + # If these connections are all in use and a new one + # is requested, the request will NOT get a connection. + # + # Setting 'max' to LESS than the number of threads means + # that some threads may starve, and you will see errors + # like 'No connections available and at max connection limit' + # + # Setting 'max' to MORE than the number of threads means + # that there are more connections than necessary. + max = ${thread[pool].max_servers} + + # Spare connections to be left idle + # + # NOTE: Idle connections WILL be closed if "idle_timeout" + # is set. This should be less than or equal to "max" above. + spare = ${thread[pool].max_spare_servers} + + # Number of uses before the connection is closed + # + # 0 means "infinite" + uses = 0 + + # The number of seconds to wait after the server tries + # to open a connection, and fails. During this time, + # no new connections will be opened. + retry_delay = 30 + + # The lifetime (in seconds) of the connection + lifetime = 0 + + # idle timeout (in seconds). A connection which is + # unused for this length of time will be closed. + idle_timeout = 60 + + # NOTE: All configuration settings are enforced. If a + # connection is closed because of "idle_timeout", + # "uses", or "lifetime", then the total number of + # connections MAY fall below "min". When that + # happens, it will open a new connection. It will + # also log a WARNING message. + # + # The solution is to either lower the "min" connections, + # or increase lifetime/idle_timeout. + } + + # Set to 'yes' to read radius clients from the database ('nas' table) + # Clients will ONLY be read on server startup. +# read_clients = yes + + # Table to keep radius client info + client_table = "nas" + + # + # The group attribute specific to this instance of rlm_sql + # + + # This entry should be used for additional instances (sql foo {}) + # of the SQL module. +# group_attribute = "${.:instance}-SQL-Group" + + # This entry should be used for the default instance (sql {}) + # of the SQL module. + group_attribute = "SQL-Group" + + # Read database-specific queries + $INCLUDE ${modconfdir}/${.:name}/main/${dialect}/queries.conf +} + +