Monday, October 29, 2018

Running php-fpm in Docker based on CentOS 7

Running php-fpm in Docker based on CentOS 7

Dockerfile:

FROM centos:centos7

RUN curl 'https://setup.ius.io/' -o setup-ius.sh \
 && bash setup-ius.sh \
 && rm -f setup-ius.sh \
 && yum -y update \
 && yum -y install \
  php71u-common \
  php71u-cli \
  php71u-fpm \
  php71u-opcache \
  php71u-xml \
  php71u-json \
  php71u-pdo \
  php71u-mysqlnd \
  php71u-intl \
  php71u-mbstring \
  php71u-mcrypt \
  php71u-gd \
  php71u-soap \
  php71u-process \
  php71u-pecl-redis \
  php71u-pecl-xdebug \
  php71u-fpm-httpd

EXPOSE 9000

CMD ["php-fpm", "-F"]

Build the docker image:

# docker build -t junhsieh/php7.1-fpm:0.0.0 .

Some important settings to be changed:

# vim /etc/php-fpm.d/www.conf

; Change ownership:

user = php-fpm
group = php-fpm

; Note: Ubuntu uses www-data user. Add php-fpm user to www-data group if the other container used it.
; # groupadd -g 33 www-data
; # useradd www-data -m -c 'web user' -u 33 -g 33
; # usermod -a -G www-data php-fpm
; # id php-fpm
; Now, restart this container to ensure php-fpm user is in www-data group.

; Bind port 9000 to the all interfaces:

listen = 9000
;listen = [::]:9000

; Note: PHP-FPM has a listen.client_allowed setting which allows you to set a list of IPs that can connect, or leave blank for any IP to connect. However, even with it being left blank, the issue still persisted. Digging into the official PHP-FPM repo, I discovered that you also need to set  listen = [::]:9000 which then began to allow any IP to connect.
; Note: https://stackoverflow.com/questions/19806945/docker-and-connections-between-containers

; Comment out the following line:

;listen.allowed_clients = 127.0.0.1

; Note: "listen.allowed_clients = any" will not work.
; Note: "listen.allowed_clients = other-container-name" will not work. IP address only.


; Uncomment the following line to debug the issue:

catch_workers_output = yes

; Note: Comment it out on production.


xdebug setting:

### xdebug setting
###
; Enable xdebug extension module
zend_extension=xdebug.so
;zend_extension=/usr/lib64/php/modules/xdebug.so

xdebug.default_enable=1
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_host=localhost
xdebug.remote_port=9009
; Note: php-fpm uses port 9000 as well.
xdebug.remote_log=/tmp/xdebug.log
xdebug.remote_connect_back=0
xdebug.remote_autostart=0
xdebug.remote_mode=req

xdebug.max_nesting_level=1000

Reference:

https://developers.redhat.com/blog/2014/12/29/running-php-fpm-in-docker/

Sunday, October 14, 2018

usermod and groupmod not found in Alpine Linux Docker Image

usermod and groupmod not found in Alpine Linux Docker Image

$ vim Dockerfile

FROM alpine:latest

RUN apk --no-cache add shadow \
  && usermod -u 2500 elasticsearch \
  && groupmod -g 2500 elasticsearch

Monday, October 8, 2018

Setup A Centralized Log Server Using Rsyslog on Ubuntu 16.04 LTS

Setup A Centralized Log Server Using Rsyslog on Ubuntu 16.04 LTS

Rsyslog Server:

# vim /etc/rsyslog.conf

# provides UDP syslog reception
module(load="imudp")
input(type="imudp" port="514")

# provides TCP syslog reception
module(load="imtcp")
input(type="imtcp" port="514")

# vim /etc/rsyslog.d/tmpl.conf

$template TmplAuth, "/var/log/client_logs/%HOSTNAME%/%PROGRAMNAME%.log"
$template TmplMsg, "/var/log/client_logs/%HOSTNAME%/%PROGRAMNAME%.log"

authpriv.* ?TmplAuth
*.info;mail.none;authpriv.none;cron.none ?TmplMsg

# systemctl restart rsyslog

Rsyslog Client:

# vim /etc/rsyslog.conf

##RULES## 
*.* @192.168.1.200:514

Note: The @ symbol before the IP address tells rsyslog to use UDP to send the messages. Change this to @@ to use TCP.

# systemctl restart rsyslog

# logger -s " This is my Rsyslog client "

# tree /var/log/client_logs/

The following is a list of RFCs that define the Syslog protocol:

RFC 3195 Reliable Delivery for syslog
RFC 5424 The Syslog Protocol
RFC 5425 TLS Transport Mapping for Syslog
RFC 5426 Transmission of Syslog Messages over UDP
RFC 5427 Textual Conventions for Syslog Management
RFC 5848 Signed Syslog Messages
RFC 6012 Datagram Transport Layer Security (DTLS) Transport Mapping for Syslog

Reference:

http://yallalabs.com/linux/how-to-setup-a-centralized-log-server-using-rsyslog-on-ubuntu-16-04-lts/

https://success.trendmicro.com/solution/TP000086250-What-are-Syslog-Facilities-and-Levels

https://en.wikipedia.org/wiki/Syslog

https://www.elastic.co/blog/how-to-centralize-logs-with-rsyslog-logstash-and-elasticsearch-on-ubuntu-14-04

https://www.elastic.co/guide/en/beats/filebeat/master/filebeat-input-syslog.html

Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address XXXXX found

Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address XXXXX found 
at sun.security.ssl.Alerts.getSSLException(Unknown Source) ~[na:1.8.0_51] 
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source) ~[na:1.8.0_51] 

# vim LDAPConnTest.java

Hashtable<String, Object> objEnvironment;
    objEnvironment = new Hashtable<String, Object>(11);
    objEnvironment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    objEnvironment.put(Context.PROVIDER_URL,  "LDAPS://domain:636");
    objEnvironment.put(Context.SECURITY_AUTHENTICATION, "simple");
    objEnvironment.put(Context.SECURITY_PRINCIPAL, <username>);
    objEnvironment.put(Context.SECURITY_CREDENTIALS, <Password>);
    objEnvironment.put("java.naming.ldap.attributes.binary", <attributes>);
    System.setProperty("javax.net.ssl.trustStore", "certificates".concat(File.separator).concat("cacerts"));
    this.objLDAPContext = new InitialLdapContext(objEnvironment, null);

# java main -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

Note: Do not use the -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true option on production server.

Improve LDAP support Endpoint identification has been enabled on LDAPS connections.

To improve the robustness of LDAPS (secure LDAP over TLS ) connections, endpoint identification algorithms have been enabled by default.

Note that there may be situations where some applications that were previously able to successfully connect to an LDAPS server may no longer be able to do so. Such applications may, if they deem appropriate, disable endpoint identification using a new system property: com.sun.jndi.ldap.object.disableEndpointIdentification.

Define this system property (or set it to true) to disable endpoint identification algorithms.

Reference:

https://stackoverflow.com/questions/51622117/issue-with-dns-naming-and-certificates-ldap-context

https://www.oracle.com/technetwork/java/javase/8u181-relnotes-4479407.html

fail to run in alpine docker with error "no such file or directory"

fail to run in alpine docker with error "no such file or directory"

Edit main.go:

# vim main.go

package main

import (
        "fmt"
        "log"
        "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Printf("Hello World\n")
        fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
        http.HandleFunc("/", handler)
        log.Fatal(http.ListenAndServe(":8080", nil))
}

Build main.go:

# CGO_ENABLED=0 go build main.go

Note: Static build: GOOS=linux GOARCH=amd64 go build main.go

Dockerfile:

#
FROM alpine:latest
RUN apk --no-cache add ca-certificates

COPY main /usr/local/bin

CMD /usr/local/bin/main

Build Docker image:

# docker build -t exp/main:0.0.0 .