How can I close a http connection with apache without any response? I would like to close the connection without any response to a request if I detect that the request is a hacking attack.
Now I have something like that:
GET / HTTP/1.0
User-Agent: Hacking-Tool
HTTP/1.1 403 Forbidden
Date: Sun, 30 Dec 2012 19:00:56 GMT
Server: Apache/2.2.0 (Linux/SUSE) mod_ssl/2.2.0 PHP/5.1.2 SVN/1.4.6
Content-Length: 13
Connection: close
Content-Type: plain/text; charset=utf-8
Stop hacking!
How can I simply close the connection so that the hacker cannot guess that I'm running a linux system. I know that I can reduce the server signature this does not matter.
You've asked two questions, try to avoid that :).
First is you want prevent OS/app fingerprinting. You can do this by removing server header, and changing apache error pages... and still with some probability attacker would be able to guess your os and http server. You can use Apache Mod Security to help yourself.
Second is closing connection without proper http response header after application level, logic execution (your app determines if request is a hacking attempt). In php I think you cannot do this. When parser is executed I think that response is already prepared by apache, and if parser does not return anything empty response or error response would be send by apache itself. And I think if you use some header filtering, and just return plain string "Hacking attempt detected. Administratiors were notified. Legal repercutions may follow." You will scare some script kiddie pretty well.
P.S. Im curious what hacking attempts will your app be able to detect? Is this CSRF token validation ? Is this simple not authenticated access attempt, or other form of Authorization checks ? Or some security mechanism that you developed ?
It is possible to to close http connection without sending any response to the client. But is rather involved. It shouldn't need to be this difficult.
IP Tables Rules:
iptables -t raw -I PREROUTING 1 -m recent --rsource --mask 255.255.255.0 --update --seconds 259200 --name DYN_DROP_IPv4 -j DROP
iptables -t raw -I OUTPUT 1 -m recent --rsource --mask 255.255.255.0 --update --seconds 259200 --name DYN_DROP_IPv4 -j DROP
ip6tables -t raw -I PREROUTING 1 -m recent --rsource --mask ffff:ffff:ffff:ffff:0:0:0:0 --update --seconds 259200 --name DYN_DROP_IPv6 -j DROP
ip6tables -t raw -I OUTPUT 1 -m recent --rsource --mask ffff:ffff:ffff:ffff:0:0:0:0 --update --seconds 259200 --name DYN_DROP_IPv6 -j DROP
httpd config rewrite rule to run the script:
# The network mask must be the same as the iptables rule mask
Define DynDropIP_QueryString '\
?action=+\
&addr=%{REMOTE_ADDR}\
&port=%{REMOTE_PORT}\
&mask_ipv4=255.255.255.0\
&mask_ipv6=ffff:ffff:ffff:ffff:0:0:0:0\
&remote_host=%{REMOTE_HOST}\
&server_name=%{SERVER_NAME}\
&server_port=%{SERVER_PORT}\
&request_method=%{REQUEST_METHOD}\
&request_uri=%{REQUEST_URI}\
&http_user_agent=%{HTTP_USER_AGENT}\
'
Define BAD_REQUESTS_REGEX '\
^/./|\
^/\.|\
^/[0-9]+|\
^/admin|\
'
Define BAD_BOTS_REGEX '\
^.$|\
11A465|\
Ahrefs|\
ArchiveBot|\
AspiegelBot|\
Baiduspider|\
'
RewriteCond %{REQUEST_URI} ${BAD_REQUESTS_REGEX} [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ${BAD_BOTS_REGEX} [NC]
# Dynamic Drop IP Script
RewriteRule ^.* /cgi-bin/DynDropIP${DynDropIP_QueryString} [PT,E=dontlog,L,END]
UnDefine DynDropIP_QueryString
UnDefine BAD_REQUESTS_REGEX
UnDefine BAD_BOTS_REGEX
cgi-bin/DynDropIP
#!/bin/sh
main() {
# Pass query string trough to the named pipe (FIFO file) daemon; Redirect stderr to bit bucket
fifo_dir='/var/run/DynDropIP/'
fifo_file='xt_recent_fifo'
if [[ -p "${fifo_dir}${fifo_file}" ]]; then
printf "%s\n" "${QUERY_STRING}" 1>"${fifo_dir}${fifo_file}" 2>/dev/null
fi
response
}
response() {
# Allow a few seconds for the firewall to be updated before responding (desire firewall to block the response)
sleep 3
# Set the HTTP response headers (404 and content type)
# end of HTTP headers (empty line i.e. 2nd consecutive line feed)
# Send 404 error page (duplicate of Apache 2.4.6 default 404 page (en))
printf "%s\n%s\n\n%s\n" \
"Status: 404 Not Found" \
"Content-type: text/html; charset=iso-8859-1" \
"\
<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL ${REQUEST_URI} was not found on this server.</p>
</body></html>\
"
}
main
/usr/local/libexec/DynDropIP/xt_recent_fifo.sh
(run this script to start the fifo and daemon)
#!/bin/bash
fifo_dir='/var/run/DynDropIP/'
fifo_file='xt_recent_fifo'
daemon='/usr/local/libexec/DynDropIP/xt_recent_fifo_daemon.sh'
# Prep and clean first
# If fifo dir is not a dir remove and make dir
if [[ ! -d "${fifo_dir}" ]]; then
rm -f "${fifo_dir}"
mkdir -p "${fifo_dir}"
fi
# If fifo file exists remove
[ -a "${fifo_dir}${fifo_file}" ] || \
[ -e "${fifo_dir}${fifo_file}" ] || \
[ -f "${fifo_dir}${fifo_file}" ] || \
[ -h "${fifo_dir}${fifo_file}" ] || \
[ -p "${fifo_dir}${fifo_file}" ] && \
rm -f "${fifo_dir}${fifo_file}"
mkfifo -m 666 "${fifo_dir}${fifo_file}"
# For SELinux - Allow apache user to write to the fifo
chcon -t httpd_sys_rw_content_t "${fifo_dir}${fifo_file}"
tail -f "${fifo_dir}${fifo_file}" | "${daemon}" &
/usr/local/libexec/DynDropIP/xt_recent_fifo_daemon.sh
#!/bin/bash
main() {
# Initialize IP address regex pattern vars
IP_RegEx
# Expected query string parameters: action (+/-), addr, port, mask_ipv4, mask_ipv6
while read QUERY_STRING
do
# Parse the query string into associative array
while IFS='=' read -r -d '&' key value && [[ -n "$key" ]]; do
declare $key="$value"
done <<<"${QUERY_STRING}&"
if validate; then
if process_address; then
update_iptables
logit
# response
destroy_tcp_socket
fi
fi
done < "${1:-/dev/stdin}"
}
# Validate action, address and mask parameters
validate() {
# Verify action parameter
if [[ "${action}" != "+" && "${action}" != "-" ]]; then
return 1 # failed: invalid action
fi
# Verify address and mask, set ip version if okay
if [[ "${addr}" =~ ^${IPV4ADDR}$ && "${mask_ipv4}" =~ ^${IPV4ADDR}$ ]]; then
ipv=4
elif [[ "${addr}" =~ ^${IPV6ADDR}$ && "${mask_ipv6}" =~ ^${IPV6ADDR}$ ]]; then
ipv=6
else
return 2 # failed: invalid address or network mask
fi
}
# Process IPvN address
process_address() {
if [[ $ipv -eq 4 ]]; then
ipv4_network_mask
if ! [[ "${maddr}" =~ ^${IPV4ADDR}$ ]]; then
return 4 # failed: invalid masked ipv4 address
fi
elif [[ $ipv -eq 6 ]]; then
ipv6_expand_address
ipv6_native_notation
ipv6_network_mask
if ! [[ "${maddr}" =~ ^${IPV6ADDR}$ ]]; then
return 6 # failed: invalid masked ipv6 address
fi
fi
}
# Compress IPv6 address (retain IPv4 dotted decimal or IPv6 native notation)
compress_address() {
if [[ $addr =~ ^((${IPV6SEG}:){6})((${IPV6SEG}:${IPV6SEG})|(${IPV4ADDR}))$ ]]; then
local IPv6_Segments IPv4_Segments pattern
IPv6_Segments=${BASH_REMATCH[1]}${BASH_REMATCH[4]}
IPv4_Segments=${BASH_REMATCH[5]}
# Suppress hextet leading zeros; Three passes to get each of three
IPv6_Segments=${IPv6_Segments//:0/:} && IPv6_Segments=${IPv6_Segments//:0/:} && IPv6_Segments=${IPv6_Segments//:0/:}
# Reconstitute empty hextets with single zero; Two passes to get every other one
IPv6_Segments=${IPv6_Segments//::/:0:} && IPv6_Segments=${IPv6_Segments//::/:0:}
# First hextet special cases (0:)
[[ $IPv6_Segments =~ ^0*([[:xdigit:]]+)(.*) ]] && IPv6_Segments="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
# Last hextet special cases (:0, only if not followed by IPv4 segment)
[[ $IPv6_Segments =~ [^:]:$ && -z $IPv4_Segments ]] && IPv6_Segments=$IPv6_Segments'0'
# Compress longest contiguous hextets of zero to "::" (leftmost tiebreaker).
for (( i=7; $i>=1; i-- ))
do
pattern=''
for (( j=0; $j<$i; j++ ))
do
pattern+=':0'
done
# Compress at beginning
[[ $IPv6_Segments =~ ^0$pattern ]] && IPv6_Segments=${IPv6_Segments/0$pattern/::} && break
# Compress in the middle or at end
[[ $IPv6_Segments =~ $pattern:0 ]] && IPv6_Segments=${IPv6_Segments/$pattern:0/::} && break
done
# Put address together and remove extra triple colons
addr=$IPv6_Segments$IPv4_Segments
addr=${addr/:::/::}
fi
}
# Expand IPv6 Address (retain dotted decimal or native notation)
ipv6_expand_address() {
local hextests num_colons additional_hextets
# Number of hextets in an expanded IPv6 address (native notation)
hextets=8
# How many colons in address
num_colons=${addr//[^:]/}
num_colons=${#num_colons}
# Is address IPv4 dotted decimal notation
[[ $addr =~ :${IPV4ADDR}$ ]] && hextets=$((hextets-1)) # ::ffff:0:0/96, ::ffff:0:0:0/96, 64:ff9b::/96
# Fix up beginning and end
[[ $addr =~ ^:: ]] && addr='0'$addr
[[ $addr =~ ::$ ]] && addr=$addr'0'
# Create additional hextets
additional_hextets=':'
for (( i=$num_colons; $i<$hextets; i++ ))
do
additional_hextets+='0:'
done
# Insert additional hextets (replace ::)
addr=${addr/::/$additional_hextets}
}
# Convert from IPv4 dotted decimal to IPv6 native notation (retain compressed / expanded)
ipv6_native_notation() {
local expanded_flag
# Ensure working with an expanded address
[[ $addr =~ :: ]] && ipv6_expand_address && expanded_flag=1
# Is address IPv4 dotted decimal notation
if [[ $addr =~ ^(.*:)(${IPV4ADDR})$ ]]; then
local IPv6_Segments IPv4_Segments
local s1 s2 s3 s4 s1s2 s3s4
IFS=. read -r s1 s2 s3 s4 <<< ${BASH_REMATCH[2]} # IPv4 Segments 1, 2, 3, & 4
s1s2=$(( ($s1 * 0x100) + $s2 )) # Hextet 7
s3s4=$(( ($s3 * 0x100) + $s4 )) # Hextet 8
IPv6_Segments=${BASH_REMATCH[1]} # Hextets 1, 2, 3, 4, 5, 6
IPv4_Segments=$( printf "%x:%x" "$s1s2" "$s3s4" ) # As Hextets 7 & 8
# Return converted native notation address (expanded)
if [[ -n $IPv6_Segments && -n $IPv4_Segments ]]; then
addr=$IPv6_Segments$IPv4_Segments
fi
fi
# Revert expansion
[[ $expanded_flag -eq 1 ]] && compress_address
}
# Convert from IPv6 native to IPv4 dotted decimal notation (retain compressed / expanded)
ipv6_dotted_decimal_notation() {
local expanded_flag
# Ensure working with an expanded address
[[ $addr =~ :: ]] && ipv6_expand_address && expanded_flag=1
# Is address IPv6 native notation
if [[ $addr =~ ^(.*:)(${IPV6SEG}:${IPV6SEG})$ ]]; then
local IPv6_Segments IPv4_Segments
local s1 s2 UB LB
IFS=: read -r s1 s2 <<< ${BASH_REMATCH[2]} # IPv6 Segments 7 & 8
UB=$((0xFF00)) # Upper Byte mask
LB=$((0x00FF)) # Lower Byte mask
IPv6_Segments=${BASH_REMATCH[1]} # Hextets 1, 2, 3, 4, 5, 6
IPv4_Segments=$(((16#$s1 & $UB) / $LB)).$((16#$s1 & $LB)).$(((16#$s2 & $UB) / $LB)).$((16#$s2 & $LB))
# Return converted dotted decimal notation address (expanded)
if [[ -n $IPv6_Segments && -n $IPv4_Segments ]]; then
addr=$IPv6_Segments$IPv4_Segments
fi
fi
# Revert expansion
[[ $expanded_flag -eq 1 ]] && compress_address
}
# Apply IPv4 network mask
ipv4_network_mask() {
local s1 s2 s3 s4
local m1 m2 m3 m4
mask=$mask_ipv4 # Mask is also used in logit
IFS=. read -r s1 s2 s3 s4 <<< $addr
IFS=. read -r m1 m2 m3 m4 <<< $mask
maddr="$((s1 & m1)).$((s2 & m2)).$((s3 & m3)).$((s4 & m4))"
}
# Apply IPv6 network mask
ipv6_network_mask() {
local s1 s2 s3 s4 s5 s6 s7 s8
local m1 m2 m3 m4 m5 m6 m7 m8
mask=$mask_ipv6 # Mask is also used in logit
IFS=: read -r s1 s2 s3 s4 s5 s6 s7 s8 <<< $addr
IFS=: read -r m1 m2 m3 m4 m5 m6 m7 m8 <<< $mask
maddr=$( \
printf "%x:%x:%x:%x:%x:%x:%x:%x" \
"$((0x$s1 & 0x$m1))" "$((0x$s2 & 0x$m2))" "$((0x$s3 & 0x$m3))" "$((0x$s4 & 0x$m4))" \
"$((0x$s5 & 0x$m5))" "$((0x$s6 & 0x$m6))" "$((0x$s7 & 0x$m7))" "$((0x$s8 & 0x$m8))" \
)
}
# Update table
update_iptables() {
# Add/Remove validated address to/from the xt_recent table (action parameter +/- determines add/remove)
# Redirect both stdout & stderr to null device so as not to inadvertently provide it to web user
if [[ -n $action && -n $maddr && -n $ipv ]]; then
printf "%s%s" $action $maddr 2>/dev/null \
|/usr/bin/tee /proc/net/xt_recent/DYN_DROP_IPv$ipv \
1>/dev/null 2>/dev/null
fi
}
# Log entry
logit() {
local log_dir='/var/log/iptables/DYN_DROP_IP/'
local log_file='DYN_DROP_IPv'$ipv'.log'
mkdir -p "$log_dir"
# Address field width padding (string length, field width, pad chr/str, pad chr/str width)
local field_width=0
[[ $ipv -eq 4 ]] && field_width=15
[[ $ipv -eq 6 ]] && field_width=39
local apad=$( logit_pad ${#addr} $field_width ' ' 4 )
local mpad=$( logit_pad ${#mask} $field_width ' ' 4 )
local mapad=$( logit_pad ${#maddr} $field_width ' ' 4 )
# Write log entry
printf '%s %s %s %s %s %s %s %s %s %s %s %s\n' \
"$( date +'%Y-%m-%d %H:%M:%S %a' )" \
"$ipv" \
"$action" \
"$addr$apad" \
"$maddr$mapad" \
"$mask$mpad" \
"$remote_host" \
"$server_name" \
"$server_port" \
"$request_method" \
"$request_uri" \
"$http_user_agent" \
>> "$log_dir$log_file"
# # Truncate to last 200 entries (skip header row)
#
# if [[ $ipv -eq 4 ]]; then
# local log_header='Date Time Day IPv Action IP Address Blocked Network Network Mask Client Web Site Scheme Method URI User Agent'
# elif [[ $ipv -eq 6 ]]; then
# local log_header='Date Time Day IPv Action IP Address Blocked Network Network Mask Client Web Site Scheme Method URI User Agent'
# fi
#
# printf '%s\n%s\n' \
# "$log_header" \
# "$(tail -n +2 $log_dir$log_file | tail -n -200)" \
# > "$log_dir$log_file"
}
# Field width padding
logit_pad() {
local str_length=$1
local field_width=$2
local pad_chr=$3
local pad_chr_width=$4 # e.g. tab width
local pad_length=$(( ($field_width - $str_length) / $pad_chr_width ))
local pad_string=''
for (( i=0; $i<$pad_length; i++ ))
do
pad_string+=$pad_chr
done
printf "%s" "$pad_string"
}
IP_RegEx() {
# IPv4 Regular Expressions
IPV4SEG='(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])' # doted decimal notation; no leading 0 (octal) or 0x (hexadecimal)
IPV4ADDR='(('${IPV4SEG}'\.){3,3}('${IPV4SEG}'){1,1})'
IPV4CIDR='(3[0-2]|[12]?[0-9])'
# IPv6 Regular Expressions
IPV6SEG='[0-9a-fA-F]{1,4}' # colon hextet notation; leading 0 permitted
IPV6SEG8='('${IPV6SEG}':){7,7}('${IPV6SEG}'){1,1}' # 1:2:3:4:5:6:7:8
IPV6SEG7='('${IPV6SEG}':){1,7}(:''){1,1}' # 1:: 1:2:3:4:5:6:7::
IPV6SEG6='('${IPV6SEG}':){1,6}(:'${IPV6SEG}'){1,1}' # 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
IPV6SEG5='('${IPV6SEG}':){1,5}(:'${IPV6SEG}'){1,2}' # 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
IPV6SEG4='('${IPV6SEG}':){1,4}(:'${IPV6SEG}'){1,3}' # 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
IPV6SEG3='('${IPV6SEG}':){1,3}(:'${IPV6SEG}'){1,4}' # 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
IPV6SEG2='('${IPV6SEG}':){1,2}(:'${IPV6SEG}'){1,5}' # 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
IPV6SEG1='('${IPV6SEG}':){1,1}(:'${IPV6SEG}'){1,6}' # 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
IPV6SEG0=':((:'${IPV6SEG}'){1,7}|:)' # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
IPV6LLZI='[fF][eE]80:(:'${IPV6SEG}'){0,4}%[0-9a-zA-Z]{1,}' # fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
IPV6V4MAP='(::|(0{1,4}:){5})[fF]{4}:'${IPV4ADDR} # ::ffff:d.d.d.d (::ffff:0:0/96 IPv4-mapped IPv6 addresses)
IPV6V4TRN='(::|(0{1,4}:){4})[fF]{4}:0{1,4}:'${IPV4ADDR} # ::ffff:0:d.d.d.d (::ffff:0:0:0/96 IPv4-translated addresses)
IPV6V4CMP='(::|(0:){6})'${IPV4ADDR} # ::d.d.d.d (IPv4-compatible (0::/96 deprecated by RFC4291))
# IPV6V4TRN='::([fF]{4}(:0{1,4}){0,1}:){0,1}'${IPV4ADDR} # ::d.d.d.d ::ffff:d.d.d.d ::ffff:0:d.d.d.d (IPv4-mapped IPv6 addresses and IPv4-translated addresses))
IPV6V4AMP='64:[fF]{2}9b:(:|(0{1,4}:){4})'${IPV4ADDR} # 64:ff9b::d.d.d.d (64:ff9b::/96 IPv4 translation addresses (algorithmic mapping RFC6052))
IPV6V4LUT='64:[fF]{2}9b:1:(:|(0{1,4}:){3})'${IPV4ADDR} # 64:ff9b:1::d.d.d.d (64:ff9b:1::/48 Local-Use IPv4/IPv6 Translation RFC8215)
# IPV6V4EMB='('${IPV6SEG}':){1,4}:'${IPV4ADDR} # 2001:db8:3:4::d.d.d.d 64:ff9b::d.d.d.d (IPv4-Embedded IPv6 Address)
IPV6ADDR='('\
'('${IPV6SEG8}')|('${IPV6SEG7}')|('${IPV6SEG6}')|('${IPV6SEG5}')|('${IPV6SEG4}')|('${IPV6SEG3}')|('${IPV6SEG2}')|('${IPV6SEG1}')|('${IPV6SEG0}')|'\
'('${IPV6LLZI}')|('${IPV6V4MAP}')|('${IPV6V4TRN}')|('${IPV6V4CMP}')|('${IPV6V4AMP}')|('${IPV6V4LUT}')'\
')'
IPV6CIDR='(12[0-8]|(1[01]|[1-9])?[0-9])'
PORT='([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])'
}
response() {
# Allow a few seconds for the firewall to be updated before responding (desire firewall to block the response)
sleep 3
# Set the HTTP response headers (404 and content type)
# end of HTTP headers (empty line i.e. 2nd consecutive line feed)
# Send 404 error page (duplicate of Apache 2.4.6 default 404 page (en))
printf "%s\n%s\n\n%s\n" \
"Status: 404 Not Found" \
"Content-type: text/html; charset=iso-8859-1" \
"\
<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL ${REQUEST_URI} was not found on this server.</p>
</body></html>\
"
}
# On linux kernel >= 4.9 you can use the ss command from iproute2 with key -K
# ss -K dst 192.168.1.214 dport = 49029
# the kernel has to be compiled with CONFIG_INET_DIAG_DESTROY option enabled.
destroy_tcp_socket() {
# if [[ "${port}" =~ ^${PORT}$ ]]; then # Strictly Regex method
# local -i port="10#${port}" 2> /dev/null # Convert to integer method
# if [[ $port -ge 1 && $port -le 65535 ]]; then
# Is integer between 1 and 65535 (inclusive)
local int_regex='^[0-9]+$'
if [[ "$port" =~ $int_regex && $port -ge 1 && $port -le 65535 ]]; then
# ss -K dst $addr dport = $port
ss -K dst $addr:$port \
1> /dev/null 2> /dev/null
fi
}
main
I found a simple way to achive what I want:
# Default hosts which will simply drop the connection
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/public
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SecRuleEngine On
SecAction "id:1,drop,phase:1"
</VirtualHost>
This requires that mod secure2 is installed and will drop all connection with unkown hosts. Be aware that you cannot access in that case your server via IP! If you need that add a vhost for your server IP
Related
I have
celery==3.1.23
Django==1.9.1
redis==2.10.5
ii redis-server 2:2.8.19-3 amd64 Persistent key-value database with networ
ii redis-tools 2:2.8.19-3 amd64 Persistent key-value database with networ
My configuration settings have the lines
# Celery
BROKER_URL = 'redis://127.0.0.1:6379/0'
BROKER_TRANSPORT = 'redis'
# start worker with '$ celery -A intro worker -l debug'
and my configuration file celery.py (standard practice is to name it this way, but confusing in my opinion) is
from __future__ import absolute_import
import os
import django
from celery import Celery
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'intro.settings')
django.setup()
app = Celery('intro')
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
The config /etc/default/celeryd (also confusing naming) is
# copy this file to /etc/default/celeryd
CELERYD_NODES="w1 w2 w3"
VIRTUAL_ENV_PATH="/srv/intro/bin"
# JRT
CELERY_BIN="${VIRTUAL_ENV_PATH}/celery"
# Where to chdir at start.
CELERYD_CHDIR="/srv/intro/intro"
# Python interpreter from environment.
ENV_PYTHON="$VIRTUAL_ENV_PATH/python"
# How to call "manage.py celeryd_multi"
CELERYD_MULTI="$ENV_PYTHON $CELERYD_CHDIR/manage.py celeryd_multi"
# How to call "manage.py celeryctl"
CELERYCTL="$ENV_PYTHON $CELERYD_CHDIR/manage.py celeryctl"
# Extra arguments to celeryd NOTE --beat is vital, otherwise scheduler
# will not run
CELERYD_OPTS="--concurrency=1 --beat"
# %n will be replaced with the nodename.
CELERYD_LOG_FILE="/var/log/celery/%n.log"
CELERYD_PID_FILE="/var/run/celery/%n.pid"
# Workers should run as an unprivileged user.
CELERYD_USER="jimmy"
CELERYD_GROUP="jimmy"
# Name of the projects settings module.
export DJANGO_SETTINGS_MODULE="intro.settings"
#CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
#export DJANGO_SETTINGS_MODULE="settings"
#CELERYD_MULTI="/home/webapps/.virtualenvs/crowdstaff/bin/django-admin.py celeryd_detach"
My /etc/init.d/celeryd file is
#!/bin/sh -e
VERSION=10.1
echo "celery init v${VERSION}."
if [ $(id -u) -ne 0 ]; then
echo "Error: This program can only be used by the root user."
echo " Unprivileged users must use the 'celery multi' utility, "
echo " or 'celery worker --detach'."
exit 1
fi
# Can be a runlevel symlink (e.g. S02celeryd)
if [ -L "$0" ]; then
SCRIPT_FILE=$(readlink "$0")
else
SCRIPT_FILE="$0"
fi
SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
DEFAULT_USER="celery"
DEFAULT_PID_FILE="/var/run/celery/%n.pid"
DEFAULT_LOG_FILE="/var/log/celery/%n.log"
DEFAULT_LOG_LEVEL="INFO"
DEFAULT_NODES="celery"
DEFAULT_CELERYD="-m celery worker --detach"
CELERY_DEFAULTS=${CELERY_DEFAULTS:-"/etc/default/${SCRIPT_NAME}"}
# Make sure executable configuration script is owned by root
_config_sanity() {
local path="$1"
local owner=$(ls -ld "$path" | awk '{print $3}')
local iwgrp=$(ls -ld "$path" | cut -b 6)
local iwoth=$(ls -ld "$path" | cut -b 9)
if [ "$(id -u $owner)" != "0" ]; then
echo "Error: Config script '$path' must be owned by root!"
echo
echo "Resolution:"
echo "Review the file carefully and make sure it has not been "
echo "modified with mailicious intent. When sure the "
echo "script is safe to execute with superuser privileges "
echo "you can change ownership of the script:"
echo " $ sudo chown root '$path'"
exit 1
fi
if [ "$iwoth" != "-" ]; then # S_IWOTH
echo "Error: Config script '$path' cannot be writable by others!"
echo
echo "Resolution:"
echo "Review the file carefully and make sure it has not been "
echo "modified with malicious intent. When sure the "
echo "script is safe to execute with superuser privileges "
echo "you can change the scripts permissions:"
echo " $ sudo chmod 640 '$path'"
exit 1
fi
if [ "$iwgrp" != "-" ]; then # S_IWGRP
echo "Error: Config script '$path' cannot be writable by group!"
echo
echo "Resolution:"
echo "Review the file carefully and make sure it has not been "
echo "modified with malicious intent. When sure the "
echo "script is safe to execute with superuser privileges "
echo "you can change the scripts permissions:"
echo " $ sudo chmod 640 '$path'"
exit 1
fi
}
if [ -f "$CELERY_DEFAULTS" ]; then
_config_sanity "$CELERY_DEFAULTS"
echo "Using config script: $CELERY_DEFAULTS"
. "$CELERY_DEFAULTS"
fi
# Sets --app argument for CELERY_BIN
CELERY_APP_ARG=""
if [ ! -z "$CELERY_APP" ]; then
CELERY_APP_ARG="--app=$CELERY_APP"
fi
CELERYD_USER=${CELERYD_USER:-$DEFAULT_USER}
# Set CELERY_CREATE_DIRS to always create log/pid dirs.
CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
if [ -z "$CELERYD_PID_FILE" ]; then
CELERYD_PID_FILE="$DEFAULT_PID_FILE"
CELERY_CREATE_RUNDIR=1
fi
if [ -z "$CELERYD_LOG_FILE" ]; then
CELERYD_LOG_FILE="$DEFAULT_LOG_FILE"
CELERY_CREATE_LOGDIR=1
fi
CELERYD_LOG_LEVEL=${CELERYD_LOG_LEVEL:-${CELERYD_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
CELERY_BIN=${CELERY_BIN:-"celery"}
CELERYD_MULTI=${CELERYD_MULTI:-"$CELERY_BIN multi"}
CELERYD_NODES=${CELERYD_NODES:-$DEFAULT_NODES}
export CELERY_LOADER
if [ -n "$2" ]; then
CELERYD_OPTS="$CELERYD_OPTS $2"
fi
CELERYD_LOG_DIR=`dirname $CELERYD_LOG_FILE`
CELERYD_PID_DIR=`dirname $CELERYD_PID_FILE`
# Extra start-stop-daemon options, like user/group.
if [ -n "$CELERYD_CHDIR" ]; then
DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYD_CHDIR"
fi
check_dev_null() {
if [ ! -c /dev/null ]; then
echo "/dev/null is not a character device!"
exit 75 # EX_TEMPFAIL
fi
}
maybe_die() {
if [ $? -ne 0 ]; then
echo "Exiting: $* (errno $?)"
exit 77 # EX_NOPERM
fi
}
create_default_dir() {
if [ ! -d "$1" ]; then
echo "- Creating default directory: '$1'"
mkdir -p "$1"
maybe_die "Couldn't create directory $1"
echo "- Changing permissions of '$1' to 02755"
chmod 02755 "$1"
maybe_die "Couldn't change permissions for $1"
if [ -n "$CELERYD_USER" ]; then
echo "- Changing owner of '$1' to '$CELERYD_USER'"
chown "$CELERYD_USER" "$1"
maybe_die "Couldn't change owner of $1"
fi
if [ -n "$CELERYD_GROUP" ]; then
echo "- Changing group of '$1' to '$CELERYD_GROUP'"
chgrp "$CELERYD_GROUP" "$1"
maybe_die "Couldn't change group of $1"
fi
fi
}
check_paths() {
if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
create_default_dir "$CELERYD_LOG_DIR"
fi
if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
create_default_dir "$CELERYD_PID_DIR"
fi
}
create_paths() {
create_default_dir "$CELERYD_LOG_DIR"
create_default_dir "$CELERYD_PID_DIR"
}
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
_get_pidfiles () {
# note: multi < 3.1.14 output to stderr, not stdout, hence the redirect.
${CELERYD_MULTI} expand "${CELERYD_PID_FILE}" ${CELERYD_NODES} 2>&1
}
_get_pids() {
found_pids=0
my_exitcode=0
for pidfile in $(_get_pidfiles); do
local pid=`cat "$pidfile"`
local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
echo "bad pid file ($pidfile)"
one_failed=true
my_exitcode=1
else
found_pids=1
echo "$pid"
fi
if [ $found_pids -eq 0 ]; then
echo "${SCRIPT_NAME}: All nodes down"
exit $my_exitcode
fi
done
}
_chuid () {
su "$CELERYD_USER" -c "$CELERYD_MULTI $*"
}
start_workers () {
if [ ! -z "$CELERYD_ULIMIT" ]; then
ulimit $CELERYD_ULIMIT
fi
_chuid $* start $CELERYD_NODES $DAEMON_OPTS \
--pidfile="$CELERYD_PID_FILE" \
--logfile="$CELERYD_LOG_FILE" \
--loglevel="$CELERYD_LOG_LEVEL" \
$CELERY_APP_ARG \
$CELERYD_OPTS
}
dryrun () {
(C_FAKEFORK=1 start_workers --verbose)
}
stop_workers () {
_chuid stopwait $CELERYD_NODES --pidfile="$CELERYD_PID_FILE"
}
restart_workers () {
_chuid restart $CELERYD_NODES $DAEMON_OPTS \
--pidfile="$CELERYD_PID_FILE" \
--logfile="$CELERYD_LOG_FILE" \
--loglevel="$CELERYD_LOG_LEVEL" \
$CELERY_APP_ARG \
$CELERYD_OPTS
}
kill_workers() {
_chuid kill $CELERYD_NODES --pidfile="$CELERYD_PID_FILE"
}
restart_workers_graceful () {
echo "WARNING: Use with caution in production"
echo "The workers will attempt to restart, but they may not be able to."
local worker_pids=
worker_pids=`_get_pids`
[ "$one_failed" ] && exit 1
for worker_pid in $worker_pids; do
local failed=
kill -HUP $worker_pid 2> /dev/null || failed=true
if [ "$failed" ]; then
echo "${SCRIPT_NAME} worker (pid $worker_pid) could not be restarted"
one_failed=true
else
echo "${SCRIPT_NAME} worker (pid $worker_pid) received SIGHUP"
fi
done
[ "$one_failed" ] && exit 1 || exit 0
}
check_status () {
my_exitcode=0
found_pids=0
local one_failed=
for pidfile in $(_get_pidfiles); do
if [ ! -r $pidfile ]; then
echo "${SCRIPT_NAME} down: no pidfiles found"
one_failed=true
break
fi
local node=`basename "$pidfile" .pid`
local pid=`cat "$pidfile"`
local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
echo "bad pid file ($pidfile)"
one_failed=true
else
local failed=
kill -0 $pid 2> /dev/null || failed=true
if [ "$failed" ]; then
echo "${SCRIPT_NAME} (node $node) (pid $pid) is down, but pidfile exists!"
one_failed=true
else
echo "${SCRIPT_NAME} (node $node) (pid $pid) is up..."
fi
fi
done
[ "$one_failed" ] && exit 1 || exit 0
}
case "$1" in
start)
check_dev_null
check_paths
start_workers
;;
stop)
check_dev_null
check_paths
stop_workers
;;
reload|force-reload)
echo "Use restart"
;;
status)
check_status
;;
restart)
check_dev_null
check_paths
restart_workers
;;
graceful)
check_dev_null
restart_workers_graceful
;;
kill)
check_dev_null
kill_workers
;;
dryrun)
check_dev_null
dryrun
;;
try-restart)
check_dev_null
check_paths
restart_workers
;;
create-paths)
check_dev_null
create_paths
;;
check-paths)
check_dev_null
check_paths
;;
*)
echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|graceful|kill|dryrun|create-paths}"
exit 64 # EX_USAGE
;;
esac
exit 0
Which is old, very long, and seems to contain nothing I can change to effect the broker used except the location of the default values script CELERY_DEFAULTS=/etc/default/celeryd (confusing name again). I admit I pretty well copied and pasted this script without a full understanding though I do know how init.d scripts work.
When I run /etc/init.d/celeryd start The workers start up, but ignore the BROKER django settings pointing to my redis server, and try to read RabbitMQ instead. The log file /var/log/celery/w1.log
[2016-11-30 23:44:51,873: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**#127.0.0.1:5672//: [Errno 111] Connection refused.
So celery is trying to use RabbitMQ, not Redis. There are other posts that complain of the same problem on Stack overflow, but none are resolved (as far as I can tell). I put djcelery in installed apps, as it seemed to make celeryd_multi management command available, but I don't want to use celery beat, and the documentation says this is no longer necessary. I have my own queue set up to run management commands, and I have had too many problems with setting up celerybeat in the past.
I have got the thing working by running sudo -u jimmy /srv/intro/bin/celery -A intro worker & and this works and uses the correct Redis queue (does anyone know why is it called a broker?), but wont restart on server power cycle, does not write to the log files, and I just don't feel this is a clean way to run celery workers.
I don't really want to use /etc/init.d scripts as this is the old way of doing things, and running as upstart has come and gone to replace this, and now systemd is the supported way of doing this (please correct me if I am wrong). There is no mention of these methods on the official documentation
http://docs.celeryproject.org/en/v4.0.0/userguide/daemonizing.html#init-script-celeryd
which makes me think that celery is no longer being supported, and perhaps there is a better maintained way of doing this. It is a wonder it has not been built into the core.
I did find this
https://github.com/celery/celery/blob/3.1/extra/supervisord/supervisord.conf
but there is no mention of broker in the config files, and I doubt that this will help me using Redis.
How do I get Celery running as a daemon to start automatically on reboot, and use Redis as a message queue, or is my only way of using Celery for asynchronous running of functions in Django to use the RabbitMQ message queue?
To ensure celery loads the correct broker, add broker parameter to Celery class.
app = Celery('intro', broker=settings.BROKER_URL)
Reference:
http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html#application
I'm trying to figure out if my server is accepting or not xmlrpc request. What I know is that when I try to access http://my_ip:8069/xmlrpc/common or http://my_ip:8069/xmlrpc/object on my browser I get a "File not found error". Is that what is expected?
Do I have to start my server with any flag to start xml-rpc suport?
Here is my openerp-server.conf
admin_passwd = my_pass
db_host = False
db_port = False
db_user = openerp
db_password = False
addons_path = /opt/openerp/v7/addons,/opt/openerp/v7/web/addons,/home/lfc/openerp/v7/addons
;Log settings
logfile = /var/log/openerp/openerp-server.log
; log_level = error
log_level = debug
And my starting script:
#!/bin/sh
### BEGIN INIT INFO
# Provides: openerp-server
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Enterprise Resource Management software
# Description: Open ERP is a complete ERP and CRM software.
### END INIT INFO
PATH=/bin:/sbin:/usr/bin
DAEMON=/opt/openerp/v7/server/openerp-server
NAME=openerp-server
DESC=openerp-server
# Specify the user name (Default: openerp).
USER=openerp
# Specify an alternate config file (Default: /etc/openerp-server.conf).
CONFIGFILE="/etc/openerp-server.conf"
# pidfile
PIDFILE=/var/run/$NAME.pid
# Additional options that are passed to the Daemon.
DAEMON_OPTS="-c $CONFIGFILE"
# Added option to debug
#DAEMON_OPTS="-c $CONFIGFILE --debug --log-level=debug"
# Log File
LOGFILE=/var/log/openerp/openerp-server.log
[ -x $DAEMON ] || exit 0
[ -f $CONFIGFILE ] || exit 0
checkpid() {
[ -f $PIDFILE ] || return 1
pid=`cat $PIDFILE`
[ -d /proc/$pid ] && return 0
return 1
}
case "${1}" in
start)
#Check if deamon is already running
checkpid
if [ "$pid" != "" ]; then
echo "$NAME already running with pid $pid."
else
#Only starts if not running
echo -n "Starting ${DESC}: "
start-stop-daemon --start --quiet --pidfile ${PIDFILE} \
--chuid ${USER} --background --make-pidfile \
--exec ${DAEMON} -- ${DAEMON_OPTS} --logfile=${LOGFILE}
echo "${NAME}, OK."
fi
;;
stop)
echo -n "Stopping ${DESC}: "
start-stop-daemon --stop --quiet --pidfile ${PIDFILE} \
--oknodo
#Check existence of PID file. If exists, then remove it
checkpid
if [ "$pid" != "" ]; then
`rm ${PIDFILE}`
echo -n "${PIDFILE} removed "
fi
echo "${NAME}, Stoped!"
;;
restart|force-reload)
echo -n "Restarting ${DESC}: "
start-stop-daemon --stop --quiet --pidfile ${PIDFILE} \
--oknodo
echo -n "\n${NAME}: STOPPED"
sleep 1
#Check existence of PID file. If exists, then remove it
checkpid
if [ "$pid" != "" ]; then
`rm ${PIDFILE}`
echo -n "\n${PIDFILE} REMOVED "
fi
sleep 1
start-stop-daemon --start --quiet --pidfile ${PIDFILE} \
--chuid ${USER} --background --make-pidfile \
--exec ${DAEMON} -- ${DAEMON_OPTS}
echo "\n${NAME}: STARTED\n"
;;
*)
N=/etc/init.d/${NAME}
echo "Usage: ${NAME} {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
You have to access it with valid data.
Common (xmlrpc/common) is for connection purposes and Object (xmlrpc/object) is to access tables and functions (modules).
For that you can create an api using Python, PHP, Java, etc
For example check this link
To check it You may use openerp-proxy project, which can be used as lib or CLI client to OpenERP / Odoo using xml-rpc or json-rpc.
So to test your connection:
$ pip install openerp_proxy # also install IPython if you like it
$ openerp_proxy # this will openen python/IPython shell
>>> db = session.connect() # This will ask you required info for connection
>>> db.registered_objects # this should return list of registered Openerp/Odoo models
Hope this will help
I installed redis2.4.14 before.
Yestoday, I got redis2.6.14, and directly "cd redis-2.6.14/src ; make && make install".
and I removed dump.rdb and redis.log of redis-2.4.14.
I also upgraded the configuration file to 2.6.14.
I added redis to service when I installed redis-2.4.14.
I execute command "service redis start", but it always hangs with no "ok" information.
[tys#localhost bin]# service redis start
Starting redis-server:
I can use redis nomally
[tys#localhost redis]# redis-cli
redis 127.0.0.1:6379> set name tys
OK
redis 127.0.0.1:6379> get name
"tys"
but if I type "ctrl + c" or "ctrl + z", "redis-cli" will hang on.
when I reboot the system, linux boot process hangs on "Starting redis-server"
(Sorry, I am too "young" to post image. https://groups.google.com/forum/#!topic/redis-db/iQnlyAAWE9Y)
But I can ssh it.It's a virtual machine.
There is no error in the redis.log.
[1420] 11 Aug 04:27:05.879 # Server started, Redis version 2.6.14
[1420] 11 Aug 04:27:05.880 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[1420] 11 Aug 04:27:05.903 * DB loaded from disk: 0.023 seconds
[1420] 11 Aug 04:27:05.903 * The server is now ready to accept connections on port 6379
Here is my redis init.d script :
#!/bin/bash
#
#redis - this script starts and stops the redis-server daemon
#
# chkconfig: 235 90 10
# description: Redis is a persistent key-value database
# processname: redis-server
# config: /etc/redis.conf
# config: /etc/sysconfig/redis
# pidfile: /var/run/redis.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
redis="/usr/local/bin/redis-server"
prog=$(basename $redis)
REDIS_CONF_FILE="/etc/redis.conf"
[ -f /etc/sysconfig/redis ] && . /etc/sysconfig/redis
lockfile=/var/lock/subsys/redis
start() {
[ -x $redis ] || exit 5
[ -f $REDIS_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $redis $REDIS_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
reload() {
echo -n $"Reloading $prog: "
killproc $redis -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
I resovled it with Josiah' help in the https://groups.google.com/forum/#!forum/redis-db.
It's "daemonize no" in my redis.conf. Redis started nomally, after I switched to "daemonize yes".
Version 3.0.1 # CentOS 6.6 - the same problem.
Tried with two different init scripts.
'daemonize yes' solves the problem!
Apache version : Apache/2.2.15 (Unix)
Operating System : Fedora release 13 (Goddard)
While loading WebSVN, it shows all repositories configured in below file ,But It shows 'Rev 0' while Click on repository name,Please see the attached screen shot.
/var/www/html/websvn/include/config.php
<?php
$config->parentPath("/repos");
$config->addRepository('landfill', 'file:///repos/proj/landfill','Projects');
$config->setTemplatePath("$locwebsvnreal/templates/calm/");
$config->setMinDownloadLevel(2);
set_time_limit(0);
$config->expandTabsBy(8);
?>
Couple of things to try.
First here's my config.php:
$config->parentPath('/proj/lamolabs.org/scm/svn');
$config->addTemplatePath($locwebsvnreal.'/templates/calm/');
$config->useTreeIndex(true); // Tree index, open by default
$config->setShowLastModInListing(true);
$config->addInlineMimeType('text/plain');
$config->allowDownload();
$config->setMinDownloadLevel(2);
$config->useGeshi();
set_time_limit(0);
$config->expandTabsBy(2);
Second, I setup my own start/stop script, /etc/init.d/svnserve, for svnserve:
#!/bin/bash
# Control script for the Subversion daemon
#
# chkconfig: 2345 89 40
# description: Subversion daemon
#
# processname: svnserve
source /etc/rc.d/init.d/functions
[ -x /usr/bin/svnserve ] || exit 1
### Default variables
SYSCONFIG="/etc/sysconfig/subversion"
### Read configuration
[ -r "$SYSCONFIG" ] && source "$SYSCONFIG"
RETVAL=0
prog="svnserve"
desc="Subversion daemon"
start() {
echo -n $"Starting $desc ($prog): "
daemon $prog -d $OPTIONS
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
echo
}
stop() {
echo -n $"Shutting down $desc ($prog): "
killproc $prog
RETVAL=$?
[ $RETVAL -eq 0 ] && success || failure
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
RETVAL=$?
;;
condrestart)
[ -e /var/lock/subsys/$prog ] && restart
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart}"
RETVAL=1
esac
exit $RETVAL
Third, I setup a config file, /etc/sysconfig/subversion, for svnserve
# Configuration file for the Subversion service
#
# To pass additional options (for instace, -r root of directory to server) to
# the svnserve binary at startup, set OPTIONS here.
#
#OPTIONS=
OPTIONS="--threads --root /proj/lamolabs.org"
I wrote about how I set this up on my blog in a post titled: Git and subversion setup on CentOS 5. The post has some additional info that might be helpful.
Let me know how you make out, I'm curious to find out what's up with your setup.
EDIT #2
/etc/httpd/conf.d/subversion.conf:
<VirtualHost *:80>
UseCanonicalName Off
ServerName websvn.lamolabs.org
ServerAlias websvn.bubba.net
DocumentRoot /var/www/websvn/current
<Directory /var/www/websvn/current>
Allow from all
</Directory>
</VirtualHost>
In Menu sytem>Administration>SElinuxManagement Disabled Selinux and now it working Fine!!
Has anyone had any success using start-stop-daemon and mono-service2 together? I've been fighting this for a few days now and have gotten various bits to work, but have had no success in getting a fully functional init script for a mono service.
Here is what I have learned to date:
The mono or mono-service exe must be named as the variable DAEMON (you can't list your exe as the DAEMON)
You must use the --background flag ... otherwise when this script is executed from a package installer (deb in my case). The service terminiates when the installer ends (has something to do with how the installer forks processes ... I havent investigated this much).
I have had success with listing the pid file with the mono-service flag in other scripts and using it to stop the daemon, but for some reason it doesnt work here. As such the script below does not stop the service - not sure why. Start works fine.
And here is my partially functional init script:
#! /bin/sh
### BEGIN INIT INFO
# Provides: ServiceName
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts and Stops Service
# Description: Service start|stop|restart
### END INIT INFO
# Author: Author
#
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Description of the service"
NAME=Service.exe
DAEMONNAME=ServiceDaemon.sh
INSTALLDIR=/usr/sbin/
DAEMON=/usr/bin/mono-service2
EXENAME=Service.exe
PIDFILE=/var/run/$DAEMONNAME.pid
DAEMON_ARGS=" -l:$PIDFILE $INSTALLDIR/$EXENAME"
#DAEMON_ARGS=" $INSTALLDIR/$EXENAME"
SCRIPTNAME=/etc/init.d/$DAEMONNAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --background --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --background --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
# Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend
# on this one. As a last resort, sleep for some time.
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:
We had a lot of issues with mono-service and ended up implementing our own "service" code in our app. Nothing hard, just grabbing some signals:
UnixSignal intr = new UnixSignal (Signum.SIGINT);
UnixSignal term = new UnixSignal (Signum.SIGTERM);
UnixSignal hup = new UnixSignal (Signum.SIGHUP);
UnixSignal usr2 = new UnixSignal (Signum.SIGUSR2);
UnixSignal[] signals = new UnixSignal[] { intr, term, hup, usr2 };
for (bool running = true; running; )
{
int idx = UnixSignal.WaitAny(signals);
if (idx < 0 || idx >= signals.Length) continue;
log.Debug("daemon: received signal " + signals[idx].Signum.ToString());
if ((intr.IsSet || term.IsSet))
{
intr.Reset ();
term.Reset ();
log.Debug("daemon: stopping...");
running = false;
}
else if (hup.IsSet)
{
// Ignore. Could be used to reload configuration.
hup.Reset();
}
else if (usr2.IsSet)
{
usr2.Reset();
// do something
}
}
I know this question is old but there are no accepted answers. I tinkered around with this for awhile too and came up with a daemon script which worked like a charm for me. I blogged about it here: http://www.geekytidbits.com/start-stop-daemon-with-mono-service2/
I got this script working with a couple of minor changes:
A pidfile in /var/run only works if you run as root - if you try to run the script without sudo, mono-service will fail silently.
Use --pidfile instead of --name to find the service to stop.
do_stop()
{
test -f $PIDFILE && kill `cat $PIDFILE` && return 2
start-stop-daemon --stop --quiet --verbose --oknodo --retry=0/30/KILL/5\
--exec mono-service2
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
So it works, I think it just because you can't stop a process by the command "start-stop-daemon"
i'm learning to use mono now,your invitation help me very much.thank you.
my english is poor,forgive my half-baked english.