{"id":325,"date":"2016-08-26T06:49:51","date_gmt":"2016-08-26T14:49:51","guid":{"rendered":"http:\/\/andrewwippler.com\/?p=325"},"modified":"2016-09-03T15:13:18","modified_gmt":"2016-09-03T23:13:18","slug":"securing-pwm","status":"publish","type":"post","link":"https:\/\/andrewwippler.com\/2016\/08\/26\/securing-pwm\/","title":{"rendered":"Securing PWM"},"content":{"rendered":"

In last week’s post<\/a> we set up PWM insecurely. In this post, we are going to secure it down and install mysql to store the reset questions. This guide assumes you have this CentOS 7 server publicly accessible with ports 80 and 443 available to the entire world. First, we will need to install mysql, set up a database, and add a user to that database. To do that,\u00a0we need to edit our manifest.pp<\/code> and append the following:<\/p>\n

 class { '::mysql::server':\r\n     root_password           => 'My4cc0unt$$password!',\r\n     remove_default_accounts => true,\r\n     package_name            => 'mariadb-server',\r\n     package_ensure          => 'installed',\r\n     service_name            => 'mariadb',\r\n }\r\n\r\n mysql::db { 'pwm':\r\n     user     => 'pwm',\r\n     password => 'pwm_passworD2!', # Can't do a password hash here :(\r\n }\r\n\r\n class { 'mysql::bindings':\r\n     java_enable => true,\r\n }\r\n\r\nfile { '\/opt\/tomcat8\/pwm\/lib\/mysql-connector-java.jar':\r\n     ensure  => link,\r\n     target  => '\/usr\/share\/java\/mysql-connector-java.jar',\r\n     require => Class['mysql::bindings']\r\n}<\/code><\/pre>\n

We will also need to install additional modules: <\/p>\n

puppet module install puppetlabs-firewall\r\npuppet module install jfryman-nginx\r\npuppet module install jfryman-selinux\r\npuppet module install danzilio-letsencrypt<\/code><\/pre>\n

Now we can set up our web server and directories by appending the following:<\/p>\n

file {\"\/var\/www\/${::hostname}\":\r\n     ensure => 'directory',\r\n     owner  => 'nginx',\r\n}\r\n\r\nfile {\"\/var\/www\/${::hostname}\/index.html\":\r\n     ensure  => 'file',\r\n     owner   => 'nginx',\r\n     content => '<html><head><meta http-equiv=\"refresh\" content=\"0;URL=\/pwm\" \/><\/head><\/html>',\r\n     require => File[\"\/var\/www\/${::hostname}\"],\r\n}\r\n\r\nfirewall { '100 allow http, https access':\r\n     dport  => [80, 443],\r\n     proto  => tcp,\r\n     action => accept,\r\n}\r\n\r\nselinux::fcontext {'set-httpd-context':\r\n     context  => \"httpd_sys_content_t\",\r\n     pathname => \"\/var\/www(\/.*)?\",\r\n}\r\n\r\nselinux::boolean {'httpd_can_network_connect': }\r\n\r\nclass { 'nginx': }\r\n\r\nnginx::resource::upstream { 'pwm':\r\n     members => [ 'localhost:8080' ],\r\n}\r\n\r\nnginx::resource::vhost { \"${::hostname}.${::domain}\":\r\n     ensure           => present,\r\n     www_root         => \"\/var\/www\/${::hostname}\/\",\r\n     #ssl              => true,\r\n\u00a0\u00a0 \u00a0 index_files\u00a0\u00a0 \u00a0\u00a0 => [],\r\n\u00a0\u00a0 \u00a0 try_files \u00a0\u00a0 \u00a0\u00a0\u00a0 => ['$uri','$uri\/index.html','@pwm'],\r\n     #rewrite_to_https => true,\r\n     #ssl_cert         => \"\/etc\/letsencrypt\/live\/${::fqdn}\/fullchain.pem\",\r\n     #ssl_key          => \"\/etc\/letsencrypt\/live\/${::fqdn}\/privkey.pem\",\r\n}\r\n\r\nnginx::resource::location{'@pwm':\r\n     proxy => 'http:\/\/pwm',\r\n     vhost => \"${::hostname}.${::domain}\",\r\n     ssl   => true,\r\n}\r\n<\/code><\/pre>\n

<\/code><\/code> Leave the ssl options commented out for now. We need the web server set up before running letsencrypt. After we save the file and run another puppet apply manifest.pp<\/code> we can add the letsencrypt information and uncomment the ssl information.<\/p>\n

class { ::letsencrypt:\r\n     email   => 'andrew.wippler@example.com',\r\n     require => Class['nginx'],\r\n}\r\n\r\nletsencrypt::certonly { 'pwm cert':\r\n     domains       => [\"${::fqdn}\"],\r\n     plugin        => 'webroot',\r\n     webroot_paths => [\"\/var\/www\/${::hostname}\"],\r\n     manage_cron   => true,\r\n }<\/code><\/pre>\n

Apply the manifest one more time and enjoy your new instance of PWM. As a reference, my entire manifest can be seen below:<\/p>\n

include git\r\ninclude java\r\n\r\ntomcat::install { '\/opt\/tomcat8':\r\n  source_url => 'https:\/\/www.apache.org\/dist\/tomcat\/tomcat-8\/v8.5.3\/bin\/apache-tomcat-8.5.3.tar.gz'\r\n}\r\n\r\ntomcat::instance { 'tomcat8-pwm':\r\n  catalina_home => '\/opt\/tomcat8',\r\n  catalina_base => '\/opt\/tomcat8\/pwm',\r\n}\r\n\r\ntomcat::war { 'pwm.war':\r\n  catalina_base => '\/opt\/tomcat8\/pwm',\r\n  war_source    => '\/path\/to\/pwm.war', # or http:\/\/domain.tld\/pwm.war\r\n  before        => File['\/opt\/tomcat8\/pwm\/lib\/mysql-connector-java.jar'],\r\n}\r\n\r\naugeas { 'web.xml':\r\n  incl => '\/opt\/tomcat8\/pwm\/webapps\/pwm\/WEB-INF\/web.xml',\r\n  context => '\/files\/opt\/tomcat8\/pwm\/webapps\/pwm\/WEB-INF\/web.xml\/web-app',\r\n  lens    => 'Xml.lns',\r\n  changes => 'set context-param[1]\/param-value\/#text \/opt\/tomcat8\/pwm\/webapps\/pwm\/WEB-INF',\r\n}\r\n\r\nclass { '::mysql::server':\r\n  root_password           => 'My4cc0unt$$password!',\r\n  remove_default_accounts => true,\r\n  package_name            => 'mariadb-server',\r\n  package_ensure   \t  => 'installed',\r\n  service_name            => 'mariadb',\r\n}\r\n\r\nmysql::db { 'pwm':\r\n  user     => 'pwm',\r\n  password => 'pwm_passworD2!', # Can't do a password hash here :(\r\n}\r\n\r\nclass { 'mysql::bindings':\r\n  java_enable => true,\r\n}\r\n\r\nfile { '\/opt\/tomcat8\/pwm\/lib\/mysql-connector-java.jar':\r\n  ensure  => link,\r\n  target  => '\/usr\/share\/java\/mysql-connector-java.jar',\r\n  require => Class['mysql::bindings']\r\n}\r\n\r\nfile {\"\/var\/www\/${::hostname}\":\r\n  ensure => 'directory',\r\n  owner  => 'nginx',\r\n}\r\n\r\nfile {\"\/var\/www\/${::hostname}\/index.html\":\r\n  ensure  => 'file',\r\n  owner   => 'nginx',\r\n  content => '<html><head><meta http-equiv=\"refresh\" content=\"0;URL=\/pwm\" \/><\/head><\/html>',\r\n  require => File[\"\/var\/www\/${::hostname}\"],\r\n}\r\n\r\nfirewall { '100 allow http, https access':\r\n  dport   => [80, 443],\r\n  proto  => tcp,\r\n  action => accept,\r\n  }\r\n\r\nselinux::fcontext {'set-httpd-context':\r\n  context  => \"httpd_sys_content_t\",\r\n  pathname => \"\/var\/www(\/.*)?\",\r\n}\r\n\r\nselinux::boolean {'httpd_can_network_connect': }\r\n\r\nclass { 'nginx': }\r\n\r\nnginx::resource::upstream { 'pwm':\r\n  members => [ 'localhost:8080' ],\r\n}<\/code><\/pre>\n
nginx::resource::vhost { \"${::hostname}.${::domain}\":\r\n     ensure           => present,\r\n     index_files      => [],\r\n     www_root         => \"\/var\/www\/${::hostname}\/\",\r\n     ssl              => true,\r\n     try_files        => ['$uri', '$uri\/index.html', '@pwm'],\r\n     rewrite_to_https => true,\r\n     ssl_cert         => \"\/etc\/letsencrypt\/live\/${::fqdn}\/fullchain.pem\",\r\n     ssl_key          => \"\/etc\/letsencrypt\/live\/${::fqdn}\/privkey.pem\",\r\n}\r\n\r\nnginx::resource::location{'@pwm':\r\n     proxy => 'http:\/\/pwm',\r\n     vhost => \"${::hostname}.${::domain}\",\r\n     ssl   => true,\r\n}<\/code><\/pre>\n
class { ::letsencrypt: \r\n    email   => 'andrew.wippler@example.com',\r\n    require => Class['nginx'],\r\n} \r\n\r\nletsencrypt::certonly { 'pwm cert':\r\n    domains       => [\"${::fqdn}\"],\r\n    plugin        => 'webroot',\r\n    webroot_paths => [\"\/var\/www\/${::hostname}\"],\r\n    manage_cron   => true, \r\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"

In last week’s post we set up PWM insecurely. In this post, we are going to secure it down and install mysql to store the reset questions. This guide assumes you have this CentOS 7 server publicly accessible with ports 80 and 443 available to the entire world. First, we will need to install mysql, […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[6,55,11],"tags":[37,42,4,46,43,29,26,52,28],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/posts\/325"}],"collection":[{"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/comments?post=325"}],"version-history":[{"count":14,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/posts\/325\/revisions"}],"predecessor-version":[{"id":373,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/posts\/325\/revisions\/373"}],"wp:attachment":[{"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/media?parent=325"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/categories?post=325"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/tags?post=325"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}