yannstatic/static/2020/01/20/Guide-installation-Nextcloud-17-(Debian-NGINX).html

3708 lines
264 KiB
HTML
Raw Normal View History

2024-10-31 20:18:37 +01:00
<!DOCTYPE html><html lang="fr">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>Guide d'installation Nextcloud 17 et plus (Debian / NGINX) - YannStatic</title>
<meta name="description" content="Guide dinstallation Nextcloud 17 et plus (Debian / NGINX)">
<link rel="canonical" href="https://static.rnmkcy.eu/2020/01/20/Guide-installation-Nextcloud-17-(Debian-NGINX).html"><link rel="alternate" type="application/rss+xml" title="YannStatic" href="/feed.xml">
<!-- - include head/favicon.html - -->
<link rel="shortcut icon" type="image/png" href="/assets/favicon/favicon.png"><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" ><!-- start custom head snippets --><link rel="stylesheet" href="/assets/css/expand.css">
<!-- end custom head snippets --><script>(function() {
window.isArray = function(val) {
return Object.prototype.toString.call(val) === '[object Array]';
};
window.isString = function(val) {
return typeof val === 'string';
};
window.hasEvent = function(event) {
return 'on'.concat(event) in window.document;
};
window.isOverallScroller = function(node) {
return node === document.documentElement || node === document.body || node === window;
};
window.isFormElement = function(node) {
var tagName = node.tagName;
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
};
window.pageLoad = (function () {
var loaded = false, cbs = [];
window.addEventListener('load', function () {
var i;
loaded = true;
if (cbs.length > 0) {
for (i = 0; i < cbs.length; i++) {
cbs[i]();
}
}
});
return {
then: function(cb) {
cb && (loaded ? cb() : (cbs.push(cb)));
}
};
})();
})();
(function() {
window.throttle = function(func, wait) {
var args, result, thisArg, timeoutId, lastCalled = 0;
function trailingCall() {
lastCalled = new Date;
timeoutId = null;
result = func.apply(thisArg, args);
}
return function() {
var now = new Date,
remaining = wait - (now - lastCalled);
args = arguments;
thisArg = this;
if (remaining <= 0) {
clearTimeout(timeoutId);
timeoutId = null;
lastCalled = now;
result = func.apply(thisArg, args);
} else if (!timeoutId) {
timeoutId = setTimeout(trailingCall, remaining);
}
return result;
};
};
})();
(function() {
var Set = (function() {
var add = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (data[i] === item) {
return;
}
}
this.size ++;
data.push(item);
return data;
};
var Set = function(data) {
this.size = 0;
this._data = [];
var i;
if (data.length > 0) {
for (i = 0; i < data.length; i++) {
add.call(this, data[i]);
}
}
};
Set.prototype.add = add;
Set.prototype.get = function(index) { return this._data[index]; };
Set.prototype.has = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (this.get(i) === item) {
return true;
}
}
return false;
};
Set.prototype.is = function(map) {
if (map._data.length !== this._data.length) { return false; }
var i, j, flag, tData = this._data, mData = map._data;
for (i = 0; i < tData.length; i++) {
for (flag = false, j = 0; j < mData.length; j++) {
if (tData[i] === mData[j]) {
flag = true;
break;
}
}
if (!flag) { return false; }
}
return true;
};
Set.prototype.values = function() {
return this._data;
};
return Set;
})();
window.Lazyload = (function(doc) {
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
var createNode = function(name, attrs) {
var node = doc.createElement(name), attr;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
node.setAttribute(attr, attrs[attr]);
}
}
return node;
};
var end = function(type, url) {
var s, q, qi, cbs, i, j, cur, val, flag;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
s[url] = true;
for (i = 0; i < q.length; i++) {
cur = q[i];
if (cur.urls.has(url)) {
qi = cur, val = qi.urls.values();
qi && (cbs = qi.callbacks);
for (flag = true, j = 0; j < val.length; j++) {
cur = val[j];
if (!s[cur]) {
flag = false;
}
}
if (flag && cbs && cbs.length > 0) {
for (j = 0; j < cbs.length; j++) {
cbs[j].call(context);
}
qi.load = true;
}
}
}
}
};
var load = function(type, urls, callback) {
var s, q, qi, node, i, cur,
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
for (i = 0; i < q.length; i++) {
cur = q[i];
if (_urls.is(cur.urls)) {
qi = cur;
break;
}
}
val = _urls.values();
if (qi) {
callback && (qi.load || qi.callbacks.push(callback));
callback && (qi.load && callback());
} else {
q.push({
urls: _urls,
callbacks: callback ? [callback] : [],
load: false
});
for (i = 0; i < val.length; i++) {
node = null, url = val[i];
if (s[url] === undefined) {
(type === 'js' ) && (node = createNode('script', { src: url }));
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
if (node) {
node.onload = (function(type, url) {
return function() {
end(type, url);
};
})(type, url);
(doc.head || doc.body).appendChild(node);
s[url] = false;
}
}
}
}
}
};
return {
js: function(url, callback) {
load('js', url, callback);
},
css: function(url, callback) {
load('css', url, callback);
}
};
})(this.document);
})();
</script><script>
(function() {
var TEXT_VARIABLES = {
version: '2.2.6',
sources: {
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
jquery: '/assets/js/jquery.min.js',
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
gitalk: {
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
},
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
},
site: {
toc: {
selectors: 'h1,h2,h3'
}
},
paths: {
search_js: '/assets/search.js'
}
};
window.TEXT_VARIABLES = TEXT_VARIABLES;
})();
</script>
</head>
<body>
<div class="root" data-is-touch="false">
<div class="layout--page js-page-root"><!----><div class="page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto">
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
<div class="header__title">
<div class="header__brand"><svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="478.9473684210526" viewBox="0, 0, 400,478.9473684210526"><g id="svgg"><path id="path0" d="M308.400 56.805 C 306.970 56.966,303.280 57.385,300.200 57.738 C 290.906 58.803,278.299 59.676,269.200 59.887 L 260.600 60.085 259.400 61.171 C 258.010 62.428,256.198 63.600,255.645 63.600 C 255.070 63.600,252.887 65.897,252.598 66.806 C 252.460 67.243,252.206 67.600,252.034 67.600 C 251.397 67.600,247.206 71.509,247.202 72.107 C 247.201 72.275,246.390 73.190,245.400 74.138 C 243.961 75.517,243.598 76.137,243.592 77.231 C 243.579 79.293,241.785 83.966,240.470 85.364 C 239.176 86.740,238.522 88.365,237.991 91.521 C 237.631 93.665,236.114 97.200,235.554 97.200 C 234.938 97.200,232.737 102.354,232.450 104.472 C 232.158 106.625,230.879 109.226,229.535 110.400 C 228.933 110.926,228.171 113.162,226.434 119.500 C 226.178 120.435,225.795 121.200,225.584 121.200 C 225.373 121.200,225.200 121.476,225.200 121.813 C 225.200 122.149,224.885 122.541,224.500 122.683 C 223.606 123.013,223.214 123.593,223.204 124.600 C 223.183 126.555,220.763 132.911,219.410 134.562 C 218.443 135.742,217.876 136.956,217.599 138.440 C 217.041 141.424,215.177 146.434,214.532 146.681 C 214.240 146.794,214.000 147.055,214.000 147.261 C 214.000 147.467,213.550 148.086,213.000 148.636 C 212.450 149.186,212.000 149.893,212.000 150.208 C 212.000 151.386,208.441 154.450,207.597 153.998 C 206.319 153.315,204.913 150.379,204.633 147.811 C 204.365 145.357,202.848 142.147,201.759 141.729 C 200.967 141.425,199.200 137.451,199.200 135.974 C 199.200 134.629,198.435 133.224,196.660 131.311 C 195.363 129.913,194.572 128.123,193.870 125.000 C 193.623 123.900,193.236 122.793,193.010 122.540 C 190.863 120.133,190.147 118.880,188.978 115.481 C 188.100 112.928,187.151 111.003,186.254 109.955 C 185.358 108.908,184.518 107.204,183.847 105.073 C 183.280 103.273,182.497 101.329,182.108 100.753 C 181.719 100.177,180.904 98.997,180.298 98.131 C 179.693 97.265,178.939 95.576,178.624 94.378 C 178.041 92.159,177.125 90.326,175.023 87.168 C 174.375 86.196,173.619 84.539,173.342 83.486 C 172.800 81.429,171.529 79.567,170.131 78.785 C 169.654 78.517,168.697 77.511,168.006 76.549 C 167.316 75.587,166.594 74.800,166.402 74.800 C 166.210 74.800,164.869 73.633,163.421 72.206 C 160.103 68.936,161.107 69.109,146.550 69.301 C 133.437 69.474,128.581 70.162,126.618 72.124 C 126.248 72.495,125.462 72.904,124.872 73.033 C 124.282 73.163,123.088 73.536,122.219 73.863 C 121.349 74.191,119.028 74.638,117.061 74.858 C 113.514 75.254,109.970 76.350,108.782 77.419 C 107.652 78.436,100.146 80.400,97.388 80.400 C 95.775 80.400,93.167 81.360,91.200 82.679 C 90.430 83.195,89.113 83.804,88.274 84.031 C 85.875 84.681,78.799 90.910,74.400 96.243 L 73.400 97.456 73.455 106.028 C 73.526 117.055,74.527 121.238,77.820 124.263 C 78.919 125.273,80.400 127.902,80.400 128.842 C 80.400 129.202,81.075 130.256,81.900 131.186 C 83.563 133.059,85.497 136.346,86.039 138.216 C 86.233 138.886,87.203 140.207,88.196 141.153 C 89.188 142.098,90.000 143.104,90.000 143.388 C 90.000 144.337,92.129 148.594,92.869 149.123 C 93.271 149.410,93.600 149.831,93.600 150.059 C 93.600 150.286,93.932 150.771,94.337 151.136 C 94.743 151.501,95.598 153.004,96.237 154.475 C 96.877 155.947,97.760 157.351,98.200 157.596 C 98.640 157.841,99.900 159.943,101.000 162.267 C 102.207 164.817,103.327 166.644,103.825 166.876 C 104.278 167.087,105.065 168.101,105.573 169.130 C 107.658 173.348,108.097 174.093,110.006 176.647 C 111.103 178.114,112.000 179.725,112.000 180.227 C 112.000 181.048,113.425 183.163,114.678 184.200 C 115.295 184.711,117.396 188.733,117.720 190.022 C 117.855 190.562,118.603 191.633,119.381 192.402 C 120.160 193.171,121.496 195.258,122.351 197.039 C 123.206 198.820,124.167 200.378,124.487 200.501 C 124.807 200.624,125.953 202.496,127.034 204.662 C 128.114 206.828,129.676 209.299,130.505 210.153 C 131.333 211.007,132.124 212.177,132.262 212.753 C 132.618 214.239,134.291 217.048,136.288 219.5
" href="/">YannStatic</a></div><!--<button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button>--><!-- <li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li> -->
<!-- Champ de recherche -->
<div id="searchbox" class="search search--dark" style="visibility: visible">
<div class="main">
<div class="search__header"></div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<!-- <div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div> -->
</div>
</div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json',
//searchResultTemplate: '<li><a href="https://static.rnmkcy.eu{url}">{date}&nbsp;{title}</a></li>'
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a></li>'
})
</script>
<!-- Fin déclaration champ de recherche --></div><nav class="navigation">
<ul><li class="navigation__item"><a href="/archive.html">Etiquettes</a></li><li class="navigation__item"><a href="/htmldoc.html">Documents</a></li><li class="navigation__item"><a href="/liens_ttrss.html">Liens</a></li><li class="navigation__item"><a href="/aide-jekyll-text-theme.html">Aide</a></li></ul>
</nav></div>
</header>
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
<div class="col-main cell cell--auto"><!-- start custom main top snippet --><div id="results-container" class="search-result js-search-result"></div><!-- end custom main top snippet -->
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1 style="color:Tomato;">Guide d'installation Nextcloud 17 et plus (Debian / NGINX)</h1></header></div><meta itemprop="headline" content="Guide d'installation Nextcloud 17 et plus (Debian / NGINX)"><div class="article__info clearfix"><ul class="left-col menu"><li>
<a class="button button--secondary button--pill button--sm"
href="/archive.html?tag=nextcloud">nextcloud</a>
</li></ul><ul class="right-col menu"><li>
<i class="far fa-calendar-alt"></i>&nbsp;<span title="Création" style="color:#FF00FF">20&nbsp;janv.&nbsp;2020</span></li></ul></div><meta itemprop="datePublished" content="2020-01-20T00:00:00+01:00">
<meta itemprop="keywords" content="nextcloud"><div class="js-article-content">
<div class="layout--article"><!-- start custom article top snippet -->
<style>
#myBtn {
display: none;
position: fixed;
bottom: 10px;
right: 10px;
z-index: 99;
font-size: 12px;
font-weight: bold;
border: none;
outline: none;
background-color: white;
color: black;
cursor: pointer;
padding: 5px;
border-radius: 4px;
}
#myBtn:hover {
background-color: #555;
}
</style>
<button onclick="topFunction()" id="myBtn" title="Haut de page">&#8679;</button>
<script>
//Get the button
var mybutton = document.getElementById("myBtn");
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
</script>
<!-- end custom article top snippet -->
<div class="article__content" itemprop="articleBody"><details>
<summary><b>Afficher/cacher Sommaire</b></summary>
<!-- affichage sommaire -->
<div class="toc-aside js-toc-root"></div>
</details><h2 id="guide-dinstallation-nextcloud-17-et-plus-debian--nginx">Guide dinstallation Nextcloud 17 et plus (Debian / NGINX)</h2>
<p><a href="https://www.c-rieger.de/nextcloud-installation-guide-debian/">Nextcloud 17 installation guide and more (Debian/NGINX)</a> de <a href="https://www.c-rieger.de/author/criegerde/">Carsten Rieger</a> · Publié 2. août 2019 · Mis à jour 30. septembre 2019</p>
<p>En suivant ce guide, vous pourrez installer et configurer Nextcloud 17 en fonction de Debian 9.x Stretch ou de Debian 10.x Buster, NGINX 1.17.x, TLSv1.3, PHP 7.3, MariaDB 10.4, Redis, fail2ban, firewall (ufw). ) et obtiendra une note A + de Nextcloud et de Qualys SSL Labs. Nous allons demander et mettre en œuvre votre / vos certificat (s) SSL à partir de Lets Encrypt. Il vous suffit de modifier les valeurs marquées en rouge ( YOUR.DEDYN.IO , 192.168.2.x , ssh port 22 ) en ce qui concerne votre environnement!</p>
<h3 id="pré-requis">Pré-requis</h3>
<p>De mon point de vue, les exigences de ce guide peuvent être considérées comme faibles: il suffit de</p>
<ul>
<li>fournir un serveur 64 bits (par exemple, Intel NUC),</li>
<li>Transférez deux ports (80 et 443) depuis Internet (votre routeur, par exemple FritzBox ou Speedport) vers votre serveur interne Nextcloud</li>
<li>et installez le système dexploitation Debian Stretch 9.x (64Bit).</li>
</ul>
<h2 id="1-installez-nginx">1. Installez NGINX</h2>
<p>Préparez votre serveur pour linstallation elle-même:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su -
(ou sudo -s)
apt install curl gnupg2 git lsb-release ssl-cert ca-certificates apt-transport-https tree locate software-properties-common dirmngr screen htop net-tools zip unzip curl ffmpeg ghostscript libfile-fcntllock-perl -y
</code></pre></div></div>
<p>Ajouter de nouveaux référentiels de logiciels</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /etc/apt/sources.list.d
echo "deb [arch=amd64] http://nginx.org/packages/mainline/debian $(lsb_release -cs) nginx" | tee nginx.list
echo "deb [arch=amd64] https://packages.sury.org/php/ $(lsb_release -cs) main" | tee php.list
echo "deb [arch=amd64] http://mirror2.hs-esslingen.de/mariadb/repo/10.4/debian $(lsb_release -cs) main" | tee mariadb.list
</code></pre></div></div>
<p>Téléchargez les clés requises pour faire confiance à toutes les nouvelles sources:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
wget -q https://packages.sury.org/php/apt.gpg -O- | apt-key add -
apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xF1656F24C74CD1D8
</code></pre></div></div>
<p>Mettez à jour votre serveur, générez des certificats auto-signés et installez nginx:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt update &amp;&amp; apt upgrade -y &amp;&amp; apt install ssl-cert -y &amp;&amp; make-ssl-cert generate-default-snakeoil
apt remove nginx nginx-extras nginx-common nginx-full -y --allow-change-held-packages
</code></pre></div></div>
<p>Assurez-vous quApache (2) ne fonctionne pas, sinon NGINX ne démarrera pas car le port requis (: 80) serait utilisé par Apache (2):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl stop apache2.service &amp;&amp; systemctl disable apache2.service
apt install nginx -y &amp;&amp; systemctl enable nginx.service
</code></pre></div></div>
<h3 id="changer-la-configuration-de-nginx">Changer la configuration de NGINX</h3>
<p>Attention remplacer 192.168.2.0/24 et 192.168.2.1 apr vote ip/24 et gateway</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak &amp;&amp; vi /etc/nginx/nginx.conf
</code></pre></div></div>
<p>Collez les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>user www-data;
worker_processes auto;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
server_names_hash_bucket_size 64;
upstream php-handler {
server unix:/run/php/php7.3-fpm.sock;
}
set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.2.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
include /etc/nginx/mime.types;
#include /etc/nginx/proxy.conf;
#include /etc/nginx/ssl.conf;
#include /etc/nginx/header.conf;
#include /etc/nginx/optimization.conf;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
sendfile on;
send_timeout 3600;
tcp_nopush on;
tcp_nodelay on;
open_file_cache max=500 inactive=10m;
open_file_cache_errors on;
keepalive_timeout 65;
reset_timedout_connection on;
server_tokens off;
resolver 192.168.2.1 valid=30s;
#resolver 127.0.0.53 valid=30s; is recommended but reuqires a valid resolver configuration
resolver_timeout 5s;
include /etc/nginx/conf.d/*.conf;
}
</code></pre></div></div>
<h3 id="redémarrez-nginx">Redémarrez NGINX</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service nginx restart
</code></pre></div></div>
<p>Créer des dossiers et appliquer des autorisations</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p /var/nc_data /var/www/letsencrypt
chown -R www-data:www-data /var/nc_data /var/www
chown -R www-data:root
</code></pre></div></div>
<h2 id="2-installez-php">2. Installez PHP</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install php7.3-fpm php7.3-gd php7.3-mysql php7.3-curl php7.3-xml php7.3-zip php7.3-intl php7.3-mbstring php7.3-json php7.3-bz2 php7.3-ldap php-apcu imagemagick php-imagick -y
</code></pre></div></div>
<p>Génial, PHP 7.3 est déjà installé. Vérifiez vos paramètres de fuseau horaire</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>date
</code></pre></div></div>
<p>et si nécessaire le régler correctement</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>timedatectl set-timezone Europe/Paris
</code></pre></div></div>
<p>Configurer PHP</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/php/7.3/fpm/pool.d/www.conf /etc/php/7.3/fpm/pool.d/www.conf.bak
cp /etc/php/7.3/cli/php.ini /etc/php/7.3/cli/php.ini.bak
cp /etc/php/7.3/fpm/php.ini /etc/php/7.3/fpm/php.ini.bak
cp /etc/php/7.3/fpm/php-fpm.conf /etc/php/7.3/fpm/php-fpm.conf.bak
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/pm.max_children = .*/pm.max_children = 240/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/pm.start_servers = .*/pm.start_servers = 20/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/pm.min_spare_servers = .*/pm.min_spare_servers = 10/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/pm.max_spare_servers = .*/pm.max_spare_servers = 20/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests = 500/pm.max_requests = 500/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.3/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/7.3/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.3/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.3/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.3/cli/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/7.3/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.3/cli/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.3/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 512M/" /etc/php/7.3/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.3/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/7.3/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.3/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.3/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.3/fpm/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/7.3/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.3/fpm/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=8/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/7.3/fpm/php.ini
sed -i "s/;emergency_restart_threshold =.*/emergency_restart_threshold = 10/" /etc/php/7.3/fpm/php-fpm.conf
sed -i "s/;emergency_restart_interval =.*/emergency_restart_interval = 1m/" /etc/php/7.3/fpm/php-fpm.conf
sed -i "s/;process_control_timeout =.*/process_control_timeout = 10s/" /etc/php/7.3/fpm/php-fpm.conf
sed -i "s/09,39.*/# &amp;/" /etc/cron.d/php
(crontab -l ; echo "09,39 * * * * /usr/lib/php/sessionclean 2&gt;&amp;1") | crontab -u root -
cp /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xml.bak
sed -i "s/rights\=\"none\" pattern\=\"PS\"/rights\=\"read\|write\" pattern\=\"PS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights\=\"none\" pattern\=\"EPI\"/rights\=\"read\|write\" pattern\=\"EPI\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights\=\"none\" pattern\=\"PDF\"/rights\=\"read\|write\" pattern\=\"PDF\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights\=\"none\" pattern\=\"XPS\"/rights\=\"read\|write\" pattern\=\"XPS\"/" /etc/ImageMagick-6/policy.xml
</code></pre></div></div>
<p>Redémarrez les deux, PHP et NGINX</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service php7.3-fpm restart &amp;&amp; service nginx restart
</code></pre></div></div>
<h2 id="3-installez-mariadb">3. Installez MariaDB</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt update &amp;&amp; apt install mariadb-server -y
</code></pre></div></div>
<p>Vérifiez la version de votre serveur de base de données:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql --version
</code></pre></div></div>
<p><em>mysql Ver 15.1 Distrib 10.4.x-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2</em> devrait apparaître.</p>
<h3 id="mariadb-sécurisé">MariaDB sécurisé</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql_secure_installation
Switch to unix_socket authentication [Y/n] N
Enter current password for root (enter for none): &lt;ENTER&gt; or type the password Set root password? [Y/n] Y
</code></pre></div></div>
<p><em>Si déjà défini lors de linstallation de MariaDB, il vous sera demandé si vous souhaitez modifier ou conserver le mot de passe.</em></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y
</code></pre></div></div>
<h3 id="configurer-mariadb">Configurer MariaDB</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service mysql stop
mv /etc/mysql/my.cnf /etc/mysql/my.cnf.bak &amp;&amp; vi /etc/mysql/my.cnf
</code></pre></div></div>
<p>Collez les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[client]
default-character-set = utf8mb4
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld_safe]
log_error=/var/log/mysql/mysql_error.log
nice = 0
socket = /var/run/mysqld/mysqld.sock
[mysqld]
basedir = /usr
bind-address = 127.0.0.1
binlog_format = ROW
bulk_insert_buffer_size = 16M
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
concurrent_insert = 2
connect_timeout = 5
datadir = /var/lib/mysql
default_storage_engine = InnoDB
expire_logs_days = 10
general_log_file = /var/log/mysql/mysql.log
general_log = 0
innodb_buffer_pool_size = 1024M
innodb_buffer_pool_instances = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 32M
innodb_max_dirty_pages_pct = 90
innodb_file_per_table = 1
innodb_open_files = 400
innodb_io_capacity = 4000
innodb_flush_method = O_DIRECT
key_buffer_size = 128M
lc_messages_dir = /usr/share/mysql
lc_messages = en_US
log_bin = /var/log/mysql/mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
log_error=/var/log/mysql/mysql_error.log
log_slow_verbosity = query_plan
log_warnings = 2
long_query_time = 1
max_allowed_packet = 16M
max_binlog_size = 100M
max_connections = 200
max_heap_table_size = 64M
myisam_recover_options = BACKUP
myisam_sort_buffer_size = 512M
port = 3306
pid-file = /var/run/mysqld/mysqld.pid
query_cache_limit = 2M
query_cache_size = 64M
query_cache_type = 1
query_cache_min_res_unit = 2k
read_buffer_size = 2M
read_rnd_buffer_size = 1M
skip-external-locking
skip-name-resolve
slow_query_log_file = /var/log/mysql/mariadb-slow.log
slow-query-log = 1
socket = /var/run/mysqld/mysqld.sock
sort_buffer_size = 4M
table_open_cache = 400
thread_cache_size = 128
tmp_table_size = 64M
tmpdir = /tmp
transaction_isolation = READ-COMMITTED
user = mysql
wait_timeout = 600
[mysqldump]
max_allowed_packet = 16M
quick
quote-names
[isamchk]
key_buffer = 16M
</code></pre></div></div>
<p>Redémarrez et connectez-vous à MariaDB</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service mysql restart &amp;&amp; mysql -uroot -p
</code></pre></div></div>
<h3 id="créer-base-nextcloud">Créer base nextcloud</h3>
<ul>
<li>la base de données <strong>nextcloud</strong></li>
<li>lutilisateur <strong>nextcloud</strong></li>
<li>et son mot de passe <strong>password</strong></li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER nextcloud@localhost identified by 'password'; GRANT ALL PRIVILEGES on nextcloud.* to nextcloud@localhost; FLUSH privileges; quit;
</code></pre></div></div>
<p>Vérifiez que le niveau disolement de la transaction a été défini sur READ_Commit et que le classement a été défini sur UTF8MB4 correctement:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql -h localhost -uroot -p -e "SELECT @@TX_ISOLATION; SELECT SCHEMA_NAME 'database', default_character_set_name 'charset', DEFAULT_COLLATION_NAME 'collation' FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='nextcloud'"
</code></pre></div></div>
<p>Si le résultat est “READ-COMMITTED” et “utf8mb4_general_ci” comme indiqué, poursuivez linstallation de redis.</p>
<h2 id="4-redis">4. Redis</h2>
<p><em>Redis, qui signifie Remote Dictionary Server (Serveur de dictionnaire à distance), est un système de stockage de données clé-valeur en mémoire, open source et rapide, pour une utilisation en tant que base de données, de cache, de courtier de messages et de file dattente. Le projet a démarré lorsque Salvatore Sanfilippo, le développeur initial de Redis, a essayé daméliorer la scalabilité de sa startup italienne. Redis offre désormais des temps de réponse inférieurs à la milliseconde permettant des millions de demandes par seconde pour des applications en temps réel dans les domaines du jeu, de la technologie publicitaire, des services financiers, des soins de santé et de lInternet des objets. Redis est un choix populaire pour la mise en cache, la gestion de session, les jeux, les classements, lanalyse en temps réel, le géospatial, lappel de voiture avec chauffeur, le chat/la messagerie, le streaming multimédia et les applications pub/sub.</em></p>
<p>Installation</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt update &amp;&amp; apt install redis-server php-redis -y
</code></pre></div></div>
<p>Changer la configuration et lappartenance à un groupe</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
sed -i "s/port 6379/port 0/" /etc/redis/redis.conf
sed -i s/\#\ unixsocket/\unixsocket/g /etc/redis/redis.conf
sed -i "s/unixsocketperm 700/unixsocketperm 770/" /etc/redis/redis.conf
sed -i "s/# maxclients 10000/maxclients 512/" /etc/redis/redis.conf
usermod -a -G redis www-data
cp /etc/sysctl.conf /etc/sysctl.conf.bak
sed -i '$avm.overcommit_memory = 1' /etc/sysctl.conf
</code></pre></div></div>
<p>Il est recommandé de redémarrer votre serveur une fois:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>shutdown -r now
</code></pre></div></div>
<h2 id="5-nextcloud">5. Nextcloud</h2>
<p>Créez les fichiers de configuration, commencez par <strong>/etc/nginx/conf.d/nextcloud.conf</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su -
[ -f /etc/nginx/conf.d/default.conf ] &amp;&amp; mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
touch /etc/nginx/conf.d/default.conf
nano /etc/nginx/conf.d/nextcloud.conf
</code></pre></div></div>
<p>ATTENTION remplacer <strong>your.dedyn.io</strong> par votre domaine<br />
Collez les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
server_name your.dedyn.io;
listen 80 default_server;
listen [::]:80 default_server;
location ^~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name your.dedyn.io;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
root /var/www/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
#SOCIAL app enabled? Please uncomment the following row
#rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
#WEBFINGER app enabled? Please uncomment the following two rows.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
client_max_body_size 10240M;
location / {
rewrite ^ /index.php$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ^~ /apps/rainloop/app/data {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
mp4;
mp4_buffer_size 100M;
mp4_max_buffer_size 1024M;
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+).php(?:$|\/) {
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ .(?:css|js|woff2?|svg|gif|map|png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$request_uri;
access_log off;
expires 360d;
}
}
</code></pre></div></div>
<p>Si vous souhaitez que votre Nextcloud sexécute dans un sous-répertoire (sous-dossier) comme https://your.dedyn.io/ nextcloud, utilisez plutôt nextcloud.conf:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
server_name your.dedyn.io;
listen 80 default_server;
listen [::]:80 default_server;
location ^~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name your.dedyn.io;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
root /var/www/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host/nextcloud/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/nextcloud/remote.php/dav;
}
#SOCIAL app enabled? Please uncomment the following row
#rewrite ^/.well-known/webfinger /nextcloud/public.php?service=webfinger last;
#WEBFINGER app enabled? Please uncomment the following two rows.
#rewrite ^/.well-known/host-meta /nextcloud/public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /nextcloud/public.php?service=host-meta-json last;
client_max_body_size 10240M;
location /nextcloud {
rewrite ^ /nextcloud/index.php$request_uri;
}
location ~ ^/nextcloud/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/nextcloud/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ^~ /nextcloud/apps/rainloop/app/data {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
mp4;
mp4_buffer_size 100M;
mp4_max_buffer_size 1024M;
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^\/nextcloud/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+).php(?:$|\/) {
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^\/nextcloud/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ .(?:css|js|woff2?|svg|gif|map|png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /nextcloud/index.php$request_uri;
access_log off;
expires 360d;
}
}
</code></pre></div></div>
<p>Créer le letsencrypt.conf</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/nginx/conf.d/letsencrypt.conf
</code></pre></div></div>
<p>Collez les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
server_name 127.0.0.1;
listen 127.0.0.1:81 default_server;
charset utf-8;
location ^~ /.well-known/acme-challenge {
default_type text/plain;
root /var/www/letsencrypt;
}
}
</code></pre></div></div>
<p>Créer le fichier ssl.conf</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/nginx/ssl.conf
</code></pre></div></div>
<p>Coller les lignes suivantes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_trusted_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
#ssl_certificate /etc/letsencrypt/rsa-certs/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/rsa-certs/privkey.pem;
#ssl_certificate /etc/letsencrypt/ecc-certs/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/ecc-certs/privkey.pem;
#ssl_trusted_certificate /etc/letsencrypt/ecc-certs/chain.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384';
ssl_ecdh_curve X448:secp521r1:secp384r1:prime256v1;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
</code></pre></div></div>
<p>Créer le proxy.conf</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/nginx/proxy.conf
</code></pre></div></div>
<p>Coller les lignes suivantes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_redirect off;
</code></pre></div></div>
<p>Créer le header.conf</p>
<p>vi /etc/nginx/header.conf</p>
<p>Coller les lignes suivantes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer" always;
#add_header Feature-Policy "accelerometer 'none'; autoplay 'self'; geolocation 'none'; midi 'none'; sync-xhr 'self' ; microphone 'self'; camera 'self'; magnetometer 'none'; gyroscope 'none'; speaker 'self'; fullscreen 'self'; payment 'none'; usb 'none'";
add_header X-Frame-Options "SAMEORIGIN";
</code></pre></div></div>
<p>Créer optimization.conf</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/nginx/optimization.conf
</code></pre></div></div>
<p>Coller les lignes suivantes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fastcgi_hide_header X-Powered-By;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_connect_timeout 3600;
fastcgi_buffers 64 64K;
fastcgi_buffer_size 256k;
fastcgi_busy_buffers_size 3840K;
fastcgi_cache_key $http_cookie$request_method$host$request_uri;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
gzip_disable "MSIE [1-6]\.";
</code></pre></div></div>
<p>Créez le php_optimization.conf</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/nginx/php_optimization.conf
</code></pre></div></div>
<p>Coller les lignes suivantes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_cache_valid 404 1m;
fastcgi_cache_valid any 1h;
fastcgi_cache_methods GET HEAD;
</code></pre></div></div>
<h3 id="améliorer-la-sécurité">Améliorer la sécurité</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
</code></pre></div></div>
<p>Sil vous plaît soyez patient, cela prendra un certain temps en fonction de votre matériel.</p>
<h3 id="redémarrez-nginx-1">Redémarrez NGINX</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sed -i s/\#\include/\include/g /etc/nginx/nginx.conf &amp;&amp; service nginx restart
</code></pre></div></div>
<h3 id="téléchargez-et-extrayez-le-logiciel-nextcloud-puis-demandez-vos-certificats-ssl-à-lets-encrypt-via-acme">Téléchargez et extrayez le logiciel Nextcloud, puis demandez vos certificats SSL à Lets Encrypt via acme:</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /usr/local/src
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xjf latest.tar.bz2 -C /var/www &amp;&amp; chown -R www-data:www-data /var/www/ &amp;&amp; rm -f latest.tar.bz2
</code></pre></div></div>
<p>Créez un utilisateur technique pour installer et renouveler vos certificats SSL</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>adduser acmeuser
usermod -a -G www-data acmeuser
</code></pre></div></div>
<p>Problème visudo</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>visudo
</code></pre></div></div>
<p>et ajoutez la ligne suivante à la fin du fichier</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>acmeuser ALL=NOPASSWD: /bin/systemctl reload nginx.service
</code></pre></div></div>
<p>par exemple, redémarrer nginx sans mot de passe.</p>
<h3 id="pour-demander-des-certificats-ssl-à-letsencrypt-il-suffit-dinstaller-acme-et-de-demander-votre--vos-certificat-s-ssl">Pour demander des certificats SSL à letsencrypt, il suffit dinstaller acme et de demander votre / vos certificat (s) SSL:</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su - acmeuser
curl https://get.acme.sh | sh
exit
</code></pre></div></div>
<h3 id="créez-trois-dossiers-pour-demander-et-stocker-vos-certificats-ssl-à-remplacez-votrededynio">Créez trois dossiers pour demander et stocker vos certificats SSL à (remplacez votre.dedyn.io):</h3>
<p>Attention , remplacer <strong>your.dedyn.io</strong> par votre domaine</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
mkdir -p /var/www/letsencrypt/.well-known/acme-challenge /etc/letsencrypt/rsa-certs /etc/letsencrypt/ecc-certs
chmod -R 775 /var/www/letsencrypt /etc/letsencrypt &amp;&amp; chown -R www-data:www-data /var/www/ /etc/letsencrypt
su - acmeuser
acme.sh --issue -d your.dedyn.io --keylength 4096 -w /var/www/letsencrypt --key-file /etc/letsencrypt/rsa-certs/privkey.pem --ca-file /etc/letsencrypt/rsa-certs/chain.pem --cert-file /etc/letsencrypt/rsa-certs/cert.pem --fullchain-file /etc/letsencrypt/rsa-certs/fullchain.pem
acme.sh --issue -d your.dedyn.io --keylength ec-384 -w /var/www/letsencrypt --key-file /etc/letsencrypt/ecc-certs/privkey.pem --ca-file /etc/letsencrypt/ecc-certs/chain.pem --cert-file /etc/letsencrypt/ecc-certs/cert.pem --fullchain-file /etc/letsencrypt/ecc-certs/fullchain.pem
exit
</code></pre></div></div>
<h3 id="appliquez-les-autorisations-à-laide-dun-script-permissionssh-">Appliquez les autorisations à laide dun script permissions.sh :</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /root/permissions.sh
</code></pre></div></div>
<p>Collez les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/bash
find /var/www/ -type f -print0 | xargs -0 chmod 0640
find /var/www/ -type d -print0 | xargs -0 chmod 0750
chown -R www-data:www-data /var/www/
chown -R www-data:www-data /var/nc_data/
chmod 0644 /var/www/nextcloud/.htaccess
chmod 0644 /var/www/nextcloud/.user.ini
chmod 600 /etc/letsencrypt/rsa-certs/fullchain.pem
chmod 600 /etc/letsencrypt/rsa-certs/privkey.pem
chmod 600 /etc/letsencrypt/rsa-certs/chain.pem
chmod 600 /etc/letsencrypt/rsa-certs/cert.pem
chmod 600 /etc/letsencrypt/ecc-certs/fullchain.pem
chmod 600 /etc/letsencrypt/ecc-certs/privkey.pem
chmod 600 /etc/letsencrypt/ecc-certs/chain.pem
chmod 600 /etc/letsencrypt/ecc-certs/cert.pem
chmod 600 /etc/ssl/certs/dhparam.pem
exit 0
</code></pre></div></div>
<p>Exécutez le script:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x /root/permissions.sh &amp;&amp; /root/permissions.sh
</code></pre></div></div>
<p>Modifiez le fichier ssl.conf et redémarrez NGINX:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sed -i '/ssl-cert-snakeoil/d' /etc/nginx/ssl.conf
sed -i s/\#\ssl/\ssl/g /etc/nginx/ssl.conf
service nginx restart
</code></pre></div></div>
<p>Installez Nextcloud en mode silencieux</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "nextcloud" --database-pass "nextcloud" --admin-user "YourNextcloudAdmin" --admin-pass "YourNextcloudAdminPasssword" --data-dir "/var/nc_data"'
</code></pre></div></div>
<p>Information</p>
<ul>
<li>Database-name “ nextcloud ”: comme défini ci-dessus lors de la création de la base de données</li>
<li>Database-user “ nextcloud ”: comme défini ci-dessus lors de la création de lutilisateur de la base de données</li>
<li>Database-pass “ nextcloud ”: comme défini ci-dessus lors de la création du mot de passe de lutilisateur</li>
<li>Admin-user “ YourNextcloudAdmin ”: votre libre choix</li>
<li>Admin-pass “ YourNextcloudAdminPasssword ”: votre libre choix</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ config:system:set trusted_domains 0 --value=your.dedyn.io'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value=https://your.dedyn.io'
cp /var/www/nextcloud/config/config.php /var/www/nextcloud/config/config.php.bak
</code></pre></div></div>
<p>Développez votre fichier Nextcloud config.php:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sed -i 's/^[ ]*//' /var/www/nextcloud/config/config.php
sed -i '/);/d' /var/www/nextcloud/config/config.php
cat &lt;&lt;EOF &gt;&gt;/var/www/nextcloud/config/config.php
'activity_expire_days' =&gt; 14,
'auth.bruteforce.protection.enabled' =&gt; true,
'blacklisted_files' =&gt;
array (
0 =&gt; '.htaccess',
1 =&gt; 'Thumbs.db',
2 =&gt; 'thumbs.db',
),
'cron_log' =&gt; true,
'enable_previews' =&gt; true,
'enabledPreviewProviders' =&gt;
array (
0 =&gt; 'OC\\Preview\\PNG',
1 =&gt; 'OC\\Preview\\JPEG',
2 =&gt; 'OC\\Preview\\GIF',
3 =&gt; 'OC\\Preview\\BMP',
4 =&gt; 'OC\\Preview\\XBitmap',
5 =&gt; 'OC\\Preview\\Movie',
6 =&gt; 'OC\\Preview\\PDF',
7 =&gt; 'OC\\Preview\\MP3',
8 =&gt; 'OC\\Preview\\TXT',
9 =&gt; 'OC\\Preview\\MarkDown',
),
'filesystem_check_changes' =&gt; 0,
'filelocking.enabled' =&gt; 'true',
'htaccess.RewriteBase' =&gt; '/',
'integrity.check.disabled' =&gt; false,
'knowledgebaseenabled' =&gt; false,
'logfile' =&gt; '/var/nc_data/nextcloud.log',
'loglevel' =&gt; 2,
'logtimezone' =&gt; 'Europe/Berlin',
'log_rotate_size' =&gt; 104857600,
'maintenance' =&gt; false,
'memcache.local' =&gt; '\\OC\\Memcache\\APCu',
'memcache.locking' =&gt; '\\OC\\Memcache\\Redis',
'overwriteprotocol' =&gt; 'https',
'preview_max_x' =&gt; 1024,
'preview_max_y' =&gt; 768,
'preview_max_scale_factor' =&gt; 1,
'redis' =&gt;
array (
'host' =&gt; '/var/run/redis/redis-server.sock',
# ATTENTION if you operate on Debian 9.x:
# 'host' =&gt; '/var/run/redis/redis.sock',
'port' =&gt; 0,
'timeout' =&gt; 0.0,
),
'quota_include_external_storage' =&gt; false,
'share_folder' =&gt; '/Shares',
'skeletondirectory' =&gt; '',
'theme' =&gt; '',
'trashbin_retention_obligation' =&gt; 'auto, 7',
'updater.release.channel' =&gt; 'stable',
);
EOF
</code></pre></div></div>
<h3 id="editer-le-nextcloud-userini">Editer le Nextcloud .user.ini</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u www-data sed -i "s/output_buffering=.*/output_buffering='Off'/" /var/www/nextcloud/.user.ini
service php7.3-fpm restart &amp;&amp; service redis-server restart &amp;&amp; service nginx restart
</code></pre></div></div>
<h3 id="ajuster-les-applications-nextcloud">Ajuster les applications Nextcloud</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ app:disable survey_client'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ app:disable firstrunwizard'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ app:enable admin_audit'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ app:enable files_pdfviewer'
</code></pre></div></div>
<p>Optimisez votre Nextcloud avec deux scripts shell</p>
<p>(a) mettre à jour votre environnement périodiquement <a href="https://github.com/criegerde/install-nextcloud/blob/master/maintenance/debian/upgrade-debian.sh">upgrade.sh</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /root/upgrade.sh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Debian 9.x 10.x
#!/bin/bash
/usr/sbin/service nginx stop
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/updater/updater.phar'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ status'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ -V'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ db:add-missing-indices'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ db:convert-filecache-bigint'
sed -i "s/output_buffering=.*/output_buffering='Off'/" /var/www/nextcloud/.user.ini
chown -R www-data:www-data /var/www/nextcloud
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ app:update --all'
/usr/sbin/service php7.3-fpm restart
/usr/sbin/service nginx restart
exit 0
</code></pre></div></div>
<blockquote>
<p>(infos: <a href="https://docs.nextcloud.com/server/15/admin_manual/configuration_database/bigint_identifiers.html">BigInt</a> , <a href="https://docs.nextcloud.com/server/15/admin_manual/configuration_server/occ_command.html?highlight=add%20missing%20indices#add-missing-indices">indices manquants</a> )</p>
</blockquote>
<p>(b) optimisez périodiquement votre Nextcloud <a href="https://github.com/criegerde/install-nextcloud/blob/master/maintenance/debian/optimize-debian.sh">Texte du lien</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nan /root/optimize.sh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/bash
# ATTENTION if you operate on Debian 9.x:
# redis-cli -s /var/run/redis/redis.sock &lt;&lt;EOF
redis-cli -s /var/run/redis/redis-server.sock &lt;&lt;EOF
FLUSHALL
quit
EOF
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ files:scan --all'
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ files:scan-app-data'
exit 0
</code></pre></div></div>
<p>Sauvegarder les deux scripts et les marquer comme exécutables</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x /root/*.sh
</code></pre></div></div>
<p>Émettez les deux fois:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/root/upgrade.sh &amp;&amp; /root/optimize.sh
</code></pre></div></div>
<p>Ajouter des tâches cron pour Nextcloud pour www-data et root</p>
<p>Pour www-data :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab -u www-data -e
</code></pre></div></div>
<p>Coller les lignes suivantes</p>
<p><code class="language-plaintext highlighter-rouge">*/5 * * * * php -f /var/www/nextcloud/cron.php &gt; /dev/null 2&gt;&amp;1</code></p>
<p>Pour root :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab -e
</code></pre></div></div>
<p>Collez les lignes suivantes:</p>
<p><code class="language-plaintext highlighter-rouge">5 1 * * * /root/optimize.sh 2&gt;&amp;1</code></p>
<h3 id="basculez-nextcloud-pour-utiliser-cronphp">Basculez Nextcloud pour utiliser cron.php</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ background:cron'
</code></pre></div></div>
<h3 id="redémarrer-tous-les-services">Redémarrer tous les services</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service mysql restart &amp;&amp; service php7.3-fpm restart &amp;&amp; service redis-server restart &amp;&amp; service nginx restart
</code></pre></div></div>
<h3 id="connectez-vous-à-votre-tout-nouveau-nextcloud-dans-votre-navigateur">Connectez-vous à votre tout nouveau Nextcloud dans votre navigateur</h3>
<p>https://your.dedyn.io/login</p>
<p>Si la vérification dintégrité dans Nextcloud échoue, essayez de modifier le fichier config.php.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u www-data sed -i "s/.*integrity.check.disabled.*/'integrity.check.disabled' =&gt; true,/g" /var/www/nextcloud/config/config.php
</code></pre></div></div>
<p>Relancez le contrôle dintégrité et redéfinissez la valeur sur false:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u www-data sed -i "s/.*integrity.check.disabled.*/'integrity.check.disabled' =&gt; false,/g" /var/www/nextcloud/config/config.php
</code></pre></div></div>
<p>Actualisez le adminpanel (F5) et le message devrait disparaître!</p>
<h2 id="6-durcissez-votre-système-avec-fail2ban-et-ufw">6. Durcissez votre système avec fail2ban et ufw</h2>
<p>Commencez par installer et configurer fail2ban, puis configurez le pare-feu ufw pour sécuriser Nextcloud.</p>
<h3 id="installer-et-configurer-fail2ban">Installer et configurer fail2ban</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt update &amp;&amp; apt install fail2ban -y
</code></pre></div></div>
<p>Collez les lignes suivantes dans le filtre fail2ban pour Nextcloud (ou <a href="https://privat.c-rieger.de/s/88dQxRYYsoR3K2Y/download?path=%2F&amp;files=nextcloud.txt">téléchargez-les en tant que fichier txt</a> pour éviter les problèmes de code WordPress!):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/fail2ban/filter.d/nextcloud.conf
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Definition]
failregex=^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: '&lt;HOST&gt;'\)","level":2,"time":".*"}$
^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","app":"core".*","message":"Login failed: '.*' \(Remote IP: '&lt;HOST&gt;'\)".*}$
^.*\"remoteAddr\":\"&lt;HOST&gt;\".*Trusted domain error.*$
</code></pre></div></div>
<p>Collez les lignes suivantes dans la prison fail2ban pour Nextcloud:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/fail2ban/jail.d/nextcloud.local
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 36000
findtime = 36000
logpath = /var/nc_data/nextcloud.log
[nginx-http-auth]
enabled = true
</code></pre></div></div>
<h3 id="redémarrez-le-service-fail2ban">Redémarrez le service fail2ban</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service fail2ban restart &amp;&amp; fail2ban-client status nextcloud
</code></pre></div></div>
<h3 id="configurez-votre-ufw-pare-feu-simple">Configurez votre ufw (pare-feu simple)</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install ufw -y
ufw allow 80/tcp &amp;&amp; ufw allow 443/tcp &amp;&amp; ufw allow 22/tcp &amp;&amp; ufw logging medium
ufw default deny incoming &amp;&amp; ufw enable &amp;&amp; service ufw restart
</code></pre></div></div>
<h2 id="61-renforcez-votre-nextcloud-avec-spamhaus-project-et-ufw">6.1 Renforcez votre Nextcloud avec Spamhaus Project et UFW</h2>
<p>Si vous souhaitez éviter les «visiteurs non privilégiés», créez simplement le script /root/ufw-spamhaus.sh et bloquez-les directement par ufw.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /root/ufw-spamhaus.sh
</code></pre></div></div>
<p>Collez les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/bash
# Thanks to @ank0m
EXEC_DATE=`date +%Y-%m-%d`
SPAMHAUS_DROP="/usr/local/src/drop.txt"
SPAMHAUS_eDROP="/usr/local/src/edrop.txt"
URL="https://www.spamhaus.org/drop/drop.txt"
eURL="https://www.spamhaus.org/drop/edrop.txt"
DROP_ADD_TO_UFW="/usr/local/src/DROP2.txt"
eDROP_ADD_TO_UFW="/usr/local/src/eDROP2.txt"
DROP_ARCHIVE_FILE="/usr/local/src/DROP_$EXEC_DATE"
eDROP_ARCHIVE_FILE="/usr/local/src/eDROP_$EXEC_DATE"
# All credits for the following BLACKLISTS goes to "The Spamhaus Project" - https://www.spamhaus.org
echo "Start time: $(date)"
echo " "
echo "Download daily DROP file:"
wget -q -O - "$URL" &gt; $SPAMHAUS_DROP
grep -v '^;' $SPAMHAUS_DROP | cut -d ' ' -f 1 &gt; $DROP_ADD_TO_UFW
echo " "
echo "Extract DROP IP addresses and add to UFW:"
cat $DROP_ADD_TO_UFW | while read line
do
/usr/sbin/ufw insert 1 deny from "$line" comment 'DROP_Blacklisted_IPs'
done
echo " "
echo "Downloading eDROP list and import to UFW"
echo " "
echo "Download daily eDROP file:"
wget -q -O - "$eURL" &gt; $SPAMHAUS_eDROP
grep -v '^;' $SPAMHAUS_eDROP | cut -d ' ' -f 1 &gt; $eDROP_ADD_TO_UFW
echo " "
echo "Extract eDROP IP addresses and add to UFW:"
cat $eDROP_ADD_TO_UFW | while read line
do
/usr/sbin/ufw insert 1 deny from "$line" comment 'eDROP_Blacklisted_IPs'
done
echo " "
#####
## To remove or revert these rules, keep the list of IPs!
## Run a command like so to remove the rules:
# while read line; do ufw delete deny from $line; done &lt; $ARCHIVE_FILE
#####
echo "Backup DROP IP address list:"
mv $DROP_ADD_TO_UFW $DROP_ARCHIVE_FILE
echo " "
echo "Backup eDROP IP address list:"
mv $eDROP_ADD_TO_UFW $eDROP_ARCHIVE_FILE
echo " "
echo End time: $(date)
</code></pre></div></div>
<p>Rendre le script exuable en émettant</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x /root/ufw-spamhaus.sh
</code></pre></div></div>
<p>et configurez-le dans votre crontab pour quil soit émis automatiquement.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(crontab -l ; echo "10 2 * * * /root/ufw-spamhaus.sh 2&gt;&amp;1") | crontab -u root -
</code></pre></div></div>
<p>Enfin effectuer une première exécution</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/root/ufw-spamhaus.sh
</code></pre></div></div>
<p>et de nombreuses règles UFW seront appliquées immédiatement. Soyez patient, cela peut prendre un certain temps.</p>
<h2 id="7-surveillez-lensemble-de-votre-système-à-laide-de-netdata">7. Surveillez lensemble de votre système à laide de netdata</h2>
<p>Démarrer le téléchargement netdata - le répertoire netdata sera créé</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install apache2-utils git gcc make autoconf automake pkg-config uuid-dev zlib1g-dev
cd /usr/local/src
git clone https://github.com/firehol/netdata.git --depth=1
cd netdata
</code></pre></div></div>
<p>Créez un fichier de mot de passe pour protéger netdata:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>htpasswd -c /etc/nginx/netdata-access YourName
</code></pre></div></div>
<p>Ensuite, exécutez le script netdata-installer.sh avec les privilèges root pour créer, installer et démarrer netdata.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./netdata-installer.sh
</code></pre></div></div>
<p>Netdata est déjà installé. Nous ferons de petits ajustements à la configuration de netdata:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/netdata/netdata.conf
</code></pre></div></div>
<p>Dans un premier temps, nous modifions la valeur pour «historique», par exemple, 14400 (4 heures de conservation des données de graphique, utilise environ 60 Mo de RAM) dans la section [global]:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>history = 14400
</code></pre></div></div>
<p>Ensuite, nous modifions la liaison dans la section [web] en localhost (127.0.0.1) uniquement:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bind to = 127.0.0.1
</code></pre></div></div>
<p>Enfin, nous améliorons les fichiers nextcloud.conf et nginx.conf pour inclure la configuration du serveur Web Netdata:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/nginx/conf.d/nextcloud.conf
</code></pre></div></div>
<p>Collez les lignes comme indiqué ci-dessous dans le fichier nextcloud.conf:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
location / {
rewrite ^ /index.php$request_uri;
}
location /netdata {
return 301 /netdata/;
}
### début insertion
location ~ /netdata/(?&lt;ndpath&gt;.*) {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/netdata-access;
proxy_http_version 1.1;
proxy_pass_request_headers on;
proxy_set_header Connection "keep-alive";
proxy_store off;
proxy_pass http://netdata/$ndpath$is_args$args;
gzip on;
gzip_proxied any;
gzip_types *;
}
### fin insertion
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
...
</code></pre></div></div>
<p>Créez le nouveau fichier /etc/nginx/conf.d/stub_status.conf:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/nginx/conf.d/stub_status.conf
</code></pre></div></div>
<p>Collez toutes les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 127.0.0.1:80 default_server;
server_name 127.0.0.1;
location /stub_status {
stub_status on;
allow 127.0.0.1;
deny all;
}
}
</code></pre></div></div>
<p>Enregistrez et quittez le fichier (: wq!) Et modifiez le fichier /etc/nginx/nginx.conf:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
http {
server_names_hash_bucket_size 64;
upstream php-handler {
server unix:/run/php/php7.3-fpm.sock;
}
## début modif
upstream netdata {
server 127.0.0.1:19999;
keepalive 64;
}
## fin modif
...
</code></pre></div></div>
<p>Enregistrez et quittez le fichier (: wq!) Et vérifiez NGINX</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nginx -t
</code></pre></div></div>
<p>Si aucune erreur napparaît, redémarrez netdata et nginx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service netdata restart &amp;&amp; service nginx restart
</code></pre></div></div>
<p>et appelez netdata dans votre navigateur</p>
<p>https: // votre.dedyn.io / netdata</p>
<p>ou en tant que site externe dans votre Nextcloud.</p>
<h2 id="8-montez-un-espace-de-stockage-supplémentaire-sur-votre-nextcloud">8. Montez un espace de stockage supplémentaire sur votre Nextcloud</h2>
<p>(a) …<a href="https://www.c-rieger.de/nextcloud-installation-guide-debian/#storage01">using a NAS</a></p>
<p>(b) …<a href="https://www.c-rieger.de/nextcloud-installation-guide-debian/#storage02">using an external/additional HDD</a></p>
<p>(c) … <a href="https://www.c-rieger.de/nextcloud-installation-guide-debian/#storage03">using Nextclouds external storage app</a></p>
<p>Vous pouvez améliorer votre Nextcloud avec des données de votre partage NAS ou dun disque dur externe.</p>
<h3 id="a-montez-vos-données-nas-sur-un-utilisateur-nextcloud-spécifique">(a) montez vos données NAS sur un utilisateur Nextcloud spécifique</h3>
<p>Il est très simple de monter un partage NAS sur votre Nextcloud à laide de cifs. Commencez par installer cifs-utils:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install cifs-utils -y
</code></pre></div></div>
<p>Puis stockez vos informations didentification dans un fichier spécial (par exemple, /root/.smbcredentials )</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /root/.smbcredentials
</code></pre></div></div>
<p>Ecrivez votre nom dutilisateur et mot de passe:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>username=NASuser
password=NASPassword
</code></pre></div></div>
<p>Enregistrez et quittez le fichier (: wq!) Et modifiez les autorisations en 0600:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod 400 /root/.smbcredentials
</code></pre></div></div>
<p>Détectez lID de lutilisateur Web (www-data) à laide de la commande id:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>id www-data
</code></pre></div></div>
<p>et gardez lidentifiant à lesprit pour le réutiliser dans / etc / fstab :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/fstab /etc/fstab.bak
vi /etc/fstab
</code></pre></div></div>
<p>Coller ce qui suit jusquà la fin du fstab</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>//&lt;NAS&gt;/&lt;share&gt; /var/nc_data/next/files cifs user,uid=33,rw,iocharset=utf8,suid,credentials=/root/.smbcredentials,file_mode=0770,dir_mode=0770 0 0
</code></pre></div></div>
<p>Veuillez remplacer **“//<NAS>/<share>“** par le suivant et, si nécessaire, l'uid = « 33 », puis essayez de monter votre NAS manuellement:</share></NAS></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mount //&lt;NAS&gt;/&lt;share&gt;/
ou
mount -a
</code></pre></div></div>
<p>Pour démonter votre NAS, lancez manuellement</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>umount //&lt;NAS&gt;/&lt;share&gt;/
ou
umount -a
</code></pre></div></div>
<p>Il sera nécessaire de numériser à nouveau vos données pour la première utilisation. Allez donc dans votre répertoire Nextcloud et exécutez les fichiers Nextclouds : recherchez lutilisateur Nextcloud approprié (par exemple, next ) ou all ( all ):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service nginx stop
cd /var/www/nextcloud
redis-cli -s /var/run/redis/redis.sock
FLUSHALL
quit
sudo -u www-data php occ files:scan --all -v
sudo -u www-data php occ files:scan-app-data -v
service nginx start
</code></pre></div></div>
<p>Après les fichiers Nextclouds: analyser toutes vos données NAS apparaîtra dans lapplication de fichier Nextcloud.<br />
Le script de permissions <permission.sh> devrait être amélioré pour démonter et monter le nouveau partage NAS monté:</permission.sh></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /root/permissions.sh
</code></pre></div></div>
<p>Ajoutez les lignes rouges au script existant:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/bash
find /var/www/ -type f -print0 | xargs -0 chmod 0640
find /var/www/ -type d -print0 | xargs -0 chmod 0750
chown -R www-data:www-data /var/www/
umount //&lt;NAS&gt;/&lt;share&gt;
chown -R www-data:www-data /var/nc_data/
mount //&lt;NAS&gt;/&lt;share&gt;
chmod 0644 /var/www/nextcloud/.htaccess
chmod 0644 /var/www/nextcloud/.user.ini
chmod 600 /etc/letsencrypt/rsa-certs/fullchain.pem
chmod 600 /etc/letsencrypt/rsa-certs/privkey.pem
chmod 600 /etc/letsencrypt/rsa-certs/chain.pem
chmod 600 /etc/letsencrypt/rsa-certs/cert.pem
chmod 600 /etc/letsencrypt/ecc-certs/fullchain.pem
chmod 600 /etc/letsencrypt/ecc-certs/privkey.pem
chmod 600 /etc/letsencrypt/ecc-certs/chain.pem
chmod 600 /etc/letsencrypt/ecc-certs/cert.pem
chmod 600 /etc/ssl/certs/dhparam.pem
</code></pre></div></div>
<p>Veuillez substituer les <code class="language-plaintext highlighter-rouge">mount umount //&lt;NAS&gt;/&lt;share&gt;</code> en fonction de votre environnement, puis enregistrez et quittez (: wq!) Le fichier. A partir de maintenant, votre NAS sera toujours disponible dans Nextcloud pour lutilisateur spécifique.</p>
<h3 id="b-monter-un-disque-dur-externe-sur-votre-nextcloud">(b) monter un disque dur externe sur votre Nextcloud</h3>
<p>Nous préparons le nouveau lecteur /dev/sda pour utilisation dans Nextcloud. Formatez-le avec un système de fichiers ext4 et montez-le de manière permanente avec une entrée dans / etc / fstab.</p>
<p>Arrêtez vos services de serveur (NGINX, PHP, MariaDB, Redis) et vérifiez la disponibilité du nouveau lecteur:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
service nginx stop &amp;&amp; service php7.3-fpm stop &amp;&amp; service redis-server stop &amp;&amp; service mysql stop
fdisk -l /dev/sda
</code></pre></div></div>
<p>Si disponible, créez une nouvelle partition avec la commande fdisk.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fdisk /dev/sda
</code></pre></div></div>
<ol>
<li>Tapez o pour créer une nouvelle table de partition.</li>
<li>Tapez n pour créer une nouvelle partition.</li>
<li>Choisissez le type de partition principale, entrez p.</li>
<li>Numéro de partition - nous avons juste besoin de 1.</li>
<li>Laissez toutes les valeurs par défaut sur le premier secteur et le dernier secteur - Appuyez sur Entrée.</li>
<li>Tapez w et appuyez sur Entrée pour écrire la partition.</li>
</ol>
<p>La partition /dev/sda1 a été créée, nous devons maintenant la formater en ext4 avec loutil mkfs. Ensuite, vérifiez la taille du volume.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkfs.ext4 /dev/sda1
fdisk -s /dev/sda1
</code></pre></div></div>
<p>Ensuite, créez un nouveau répertoire local “nc_data” et montez “/ dev / sda1” sur ce répertoire.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p /nc_data
</code></pre></div></div>
<p>Pour monter définitivement un nouveau disque, nous ajoutons la nouvelle configuration de montage au fichier fstab. Fstab ouvert avec vom:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/fstab
</code></pre></div></div>
<p>Collez la configuration ci-dessous à la fin du fichier.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/dev/sda1 /nc_data ext4 defaults 0 1
</code></pre></div></div>
<p>Enregistrer fstab et quitter:</p>
<p>Maintenant, montez le disque et assurez-vous quil ny a pas derreur.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mount -a
df -h
</code></pre></div></div>
<p>Au moins, vous devez déplacer votre répertoire de données Nextcloud actuel vers le nouveau répertoire monté.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chown -R www-data:www-data /nc_data
rsync -av /var/nc_data/ /nc_data
</code></pre></div></div>
<p>et pointez-le dans le fichier config.php de Nextcloud.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u www-data vi /var/www/nextcloud/config/config.php
</code></pre></div></div>
<p>Changer le répertoire de données</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
'datadirectory' =&gt; '/nc_data',
...
</code></pre></div></div>
<p>Enfin, redémarrez les services de votre serveur et effectuez une nouvelle analyse de fichiers:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service nginx stop &amp;&amp; service php7.3-fpm restart &amp;&amp; service redis-server restart &amp;&amp; service mysql restart
cd /var/www/nextcloud
redis-cli -s /var/run/redis/redis.sock
FLUSHALL
quit
sudo -u www-data php occ files:scan --all -v
sudo -u www-data php occ files:scan-app-data -v
service nginx restart
</code></pre></div></div>
<p>A partir de maintenant, vos données Nextcloud seront stockées sur votre disque dur externe.</p>
<h3 id="c-application-de-stockage-externe-nextclouds">(c) Application de stockage externe Nextclouds</h3>
<p>En tant quextension pour ( a ) et ( b ), vous pouvez activer l <a href="https://docs.nextcloud.com/server/15/admin_manual/configuration_files/external_storage_configuration_gui.html#configuring-external-storage-gui">application de stockage externe</a> et bénéficier de nombreux avantages:</p>
<ul>
<li>les fichiers peuvent être créés, édités et supprimés des deux côtés: à lintérieur et à lextérieur de Nextcloud</li>
<li>vous êtes autorisé à monter des services et des périphériques de stockage externes en tant que périphériques de stockage Nextcloud secondaires</li>
<li>les utilisateurs sont autorisés à monter leurs propres services de stockage externe</li>
</ul>
<p>Si vous souhaitez utiliser Samba, émettez la déclaration suivante</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install php-smbclient smbclient -y
</code></pre></div></div>
<p>et redémarrez PHP</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service php7.3-fpm restart
</code></pre></div></div>
<h2 id="9-installez-msmtp-pour-envoyer-des-mails-au-serveur">9. Installez msmtp pour envoyer des mails au serveur</h2>
<p>(a) <a href="https://www.c-rieger.de/nextcloud-installation-guide-debian/#fail2banmails">configure fail2ban system-notification mails</a></p>
<p>(b) <a href="https://www.c-rieger.de/nextcloud-installation-guide-debian/#apticronmails">install apticron and configure system update-notification mails</a></p>
<p>Première installation msmtp</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
apt update &amp;&amp; apt upgrade -y &amp;&amp; apt install msmtp msmtp-mta mailutils -y
</code></pre></div></div>
<p>Créez votre configuration: créez le fichier, puis collez et modifiez les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/msmtprc
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>defaults
port 587
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
#Your Mail:
account yourmail@domain.com
#Your SMTP-Server:
host smtp.domain.com
#Mails will be sent from:
from yourmail@domain.com
auth on
#Your Mailaccount:
user yourmail@domain.com
#Your Password:
password yOUr-S3CrET
#Default Mailaccount:
account default: yourmail@domain.com
aliases /etc/aliases
# find out more about the configuration here: https://marlam.de/msmtp/msmtprc.txt
logfile /var/log/msmtp/msmtp.log
</code></pre></div></div>
<p>Définir la permission appropriée</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod 600 /etc/msmtprc
</code></pre></div></div>
<p>et testez votre configuration de serveur de courrier en émettant</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "Sending test mail..." | mail -s "Subject" yourmail@domain.com
</code></pre></div></div>
<p>Modifiez logrotate pour gérer correctement msmtp. Créer et éditer le fichier</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/logrotate.d/msmtp
</code></pre></div></div>
<p>et collez toutes les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/var/log/msmtp/*.log {
rotate 12
monthly
compress
missingok
notifempty
}
</code></pre></div></div>
<p>Modifier PHP pour utiliser msmtp dans PHP</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/php/7.3/fpm/php.ini
</code></pre></div></div>
<p>Définissez le sendmail_path comme suit</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sendmail_path = "/usr/bin/msmtp -t"
</code></pre></div></div>
<p>et redémarrez php</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service php7.3-fpm restart
</code></pre></div></div>
<p>Définissez enfin vos alias de messagerie: ouvrez le fichier</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/aliases
</code></pre></div></div>
<p>coller et modifier les lignes suivantes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root: yourmail@domain.com
default: yourmail@domain.com
</code></pre></div></div>
<p>A partir de maintenant votre système est préparé pour envoyer des mails. Si vous voulez que fail2ban vous tienne au courant, suivez le chapitre suivant:</p>
<h3 id="a-configurer-les-mails-de-notification-du-système-fail2ban">(a) configurer les mails de notification du système fail2ban</h3>
<p>Nous substituons lutilisateur root dans fail2ban-config pour recevoir les mails détat de fail2ban à lavenir. Ces e-mails contiendront à la fois le statut fail2ban (arrêté / démarré) et, en cas déchec de la connexion, ladresse IP bannie. Editez le fichier de configuration fail2ban</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.conf.bak
nano /etc/fail2ban/jail.conf
</code></pre></div></div>
<p>et remplacez au moins les paramètres <strong>yourmail@domain.com, mail, action = %(action_mwl)s</strong> en fonction de votre système:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
destemail = yourmail@domain.com
...
sender = yourmail@domain.com
...
mta = mail
...
# action = %(action_)s
action = %(action_mwl)s
...
</code></pre></div></div>
<p>Enregistrez et quittez (: wq!) La configuration fail2ban. Pour éviter (plusieurs) mails sur chaque redémarrage fail2ban, créez simplement un nouveau fichier et copiez-le comme indiqué ci-dessous:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/fail2ban/action.d/mail-buffered.local
</code></pre></div></div>
<p>Coller les lignes suivantes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Definition]
actionstart =
actionstop =
</code></pre></div></div>
<p>Copier le fichier</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/mail.local
cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/mail-whois-lines.local
cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/mail-whois.local
cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/sendmail-buffered.local
cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/sendmail-common.local
</code></pre></div></div>
<p>Redémarrez le service fail2ban et vous serez (seulement) informé si Fail2ban a bloqué de nouvelles adresses IP</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service fail2ban restart
</code></pre></div></div>
<p>automatiquement</p>
<h3 id="b-installer-apticron-et-configurer-les-mails-de-notification-de-mise-à-jour-du-système">(b) installer apticron et configurer les mails de notification de mise à jour du système</h3>
<p>Si vous utilisez APTICRON, votre système peut également envoyer des courriels en cas de mises à jour système disponibles.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install apticron -y
</code></pre></div></div>
<p>Après avoir installé APTICRON, vous devez modifier la configuration et substituer au moins votre adresse EMAIL, SYSTEM, NOTIFY_NO_UPDATES et CUSTOM_FROM.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/apticron/apticron.conf /etc/apticron/apticron.conf.bak
nano /etc/apticron/apticron.conf
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
EMAIL="yourmail@domain.com"
...
SYSTEM="your.dedyn.io"
...
NOTIFY_HOLDS="1"
...
NOTIFY_NO_UPDATES="1"
...
CUSTOM_SUBJECT='$SYSTEM: $NUM_PACKAGES package update(s)'
...
CUSTOM_NO_UPDATES_SUBJECT='$SYSTEM: no updates available'
...
CUSTOM_FROM="yourmail@domain.com"
...
</code></pre></div></div>
<p>Pour lancer et vérifier APTICRON, appelez simplement</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apticron
</code></pre></div></div>
<p>et vous recevrez un email envoyé par APTICRON. Maintenant, vous êtes un peu plus en sécurité.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/cron.d/apticron /etc/cron.d/apticron.bak
nano /etc/cron.d/apticron
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">30 7 * * * root if test -x /usr/sbin/apticron; then /usr/sbin/apticron --cron; else true; fi</code></p>
<p>Apticron va maintenant être exécuté par cron.d. Vous pouvez modifier lheure de début, par exemple, tous les jours à 7 h 30.</p>
<h2 id="10-un-deuxième-facteur-pour-ssh-2fa---authentification-à-deux-facteurs">10. Un deuxième facteur pour ssh (2FA - authentification à deux facteurs)</h2>
<p>Les étapes suivantes concernent le système (critique) et ne sont recommandées que pour les utilisateurs avancés de Linux. Si la configuration de ssh échoue, vous ne pourrez plus vous connecter à votre système via ssh. La condition préalable requise est un serveur ssh sur lequel vous pouvez vous connecter à laide dune clé privée / publique uniquement!</p>
<p>Installez le logiciel pour 2FA (authentification à deux facteurs) avec votre application OTP AUTH préférée.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install libpam-google-authenticator -y
</code></pre></div></div>
<p>Quittez le shell racine et exécutez la commande suivante en tant que votre <nom de="" votre-utilisateur-ubuntu=""> et PAS en tant que root:</nom></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>exit
google-authenticator
</code></pre></div></div>
<p>On vous demandera:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Do you want authentication tokens to be time-based (y/n) y
image
Do you want me to update your "~/.google_authenticator" file (y/n) y
Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y
By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n) n
If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y
</code></pre></div></div>
<p>Revenez à la racine-Shell</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
</code></pre></div></div>
<p>Sauvegardez la configuration actuelle et configurez votre serveur ssh</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
nano /etc/pam.d/sshd
</code></pre></div></div>
<p>Changer le fichier à la mienne:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@include common-auth
@include common-password
auth required pam_google_authenticator.so
account required pam_nologin.so
@include common-account
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
session required pam_loginuid.so
session optional pam_keyinit.so force revoke
@include common-session
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate
session optional pam_mail.so standard noenv # [1]
session required pam_limits.so
session required pam_env.so # [1]
session required pam_env.so user_readenv=1 envfile=/etc/default/locale
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
</code></pre></div></div>
<p>Sauvegarder et quitter (: wq!) Le fichier.</p>
<p>Sil nest pas déjà créé, créez dabord votre clé RSA 4096 bits (SSH):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~
ssh-keygen -q -f /etc/ssh/ssh_host_rsa_key -N '' -b 4096 -t rsa
</code></pre></div></div>
<p>Si vous êtes invité à écraser la clé existante, confirmez avec “Y”. Ensuite, sauvegardez, éditez et changez votre configuration SSH en un exemple</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mv /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
nano /etc/ssh/sshd_config
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Port 22
Port 1234 #your decision, but keep UFW in mind!
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
ServerKeyBits 4096
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 30s
PermitRootLogin no
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
IgnoreRhosts yes
UseDNS yes
RhostsRSAAuthentication no
HostbasedAuthentication no
IgnoreUserKnownHosts yes
PermitEmptyPasswords no
MaxAuthTries 3
MaxSessions 3
ChallengeResponseAuthentication yes
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost no
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
Banner /etc/issue
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
UsePAM yes
AllowTcpForwarding no
AllowUsers ubuntuuser #&lt;your-ubuntu-user-name&gt; for e.g. putty or ssh native
AuthenticationMethods publickey,password publickey,keyboard-interactive
</code></pre></div></div>
<p>Si vous avez changé le port ssh en 1234 , assurez-vous davoir modifié votre configuration ufw et ajustez le nom dutilisateur dans AllowUsers ubuntuuser .</p>
<p>Collez votre clé publique dans le magasin de clés de &lt; ubuntuuser &gt; (le guide dutilisation d ubuntu):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano ~/.ssh/authorized_keys
</code></pre></div></div>
<p>et définir les autorisations appropriées:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo chown -R ubuntuuser:ubuntuuser ~/.ssh
sudo chmod 700 ~/.ssh
sudo chmod 600 ~/.ssh/authorized_keys
</code></pre></div></div>
<p>Puis redémarrez votre serveur ssh</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service ssh restart
</code></pre></div></div>
<p>et reconnectez-vous à votre serveur en utilisant une nouvelle fenêtre de session . Ceci est votre dernier recours si vous avez mal configuré votre serveur ssh ;-). A partir de maintenant votre clé privée est nécessaire, vous serez invité à entrer votre mot de passe et enfin votre nouveau deuxième facteur.</p>
<p>image1<br />
Authentification par clé publique et mot de passe ssh-user</p>
<p>image2<br />
Code de vérification (OTP 2FA)</p>
<p>Démarrez votre application, par exemple OTP AUTH ou Google Authenticator, et lisez votre deuxième facteur pour accéder à votre serveur.</p>
<p>image3<br />
Connecté</p>
<p>Vous serez connecté en utilisant votre deuxième facteur.</p>
<h2 id="11-analysez-votre-serveur-en-utilisant-logwatch">11. Analysez votre serveur en utilisant logwatch</h2>
<p>Première installation de logwatch</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt update &amp;&amp; apt install logwatch -y
</code></pre></div></div>
<p>puis copiez les fichiers de configuration par défaut dans le dossier logwatch:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /usr/share/logwatch/default.conf/logfiles/http.conf /etc/logwatch/conf/logfiles/nginx.conf
cp /usr/share/logwatch/default.conf/services/http.conf /etc/logwatch/conf/services/nginx.conf
cp /usr/share/logwatch/scripts/services/http /usr/share/logwatch/scripts/services/nginx
cp /usr/share/logwatch/default.conf/services/http-error.conf /etc/logwatch/conf/services/nginx-error.conf
cp /usr/share/logwatch/scripts/services/http-error /etc/logwatch/scripts/services/nginx-error
cp /etc/logwatch/conf/logfiles/nginx.conf /etc/logwatch/conf/logfiles/nginx.conf.org.bak
</code></pre></div></div>
<p>Editez le fichier /etc/logwatch/conf/logfiles/nginx.conf pour le mien</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/logwatch/conf/logfiles/nginx.conf
</code></pre></div></div>
<p>Remplacez le fichier entier par:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>########################################################
# Define log file group for NGINX
########################################################
# What actual file? Defaults to LogPath if not absolute path....
#LogFile = httpd/*access_log
#LogFile = apache/*access.log.1
#LogFile = apache/*access.log
#LogFile = apache2/*access.log.1
#LogFile = apache2/*access.log
#LogFile = apache2/*access_log
#LogFile = apache-ssl/*access.log.1
#LogFile = apache-ssl/*access.log
LogFile = nginx/*access.log
LogFile = nginx/*error.log
LogFile = nginx/*access.log.1
LogFile = nginx/*error.log.1
# If the archives are searched, here is one or more line
# (optionally containing wildcards) that tell where they are...
#If you use a "-" in naming add that as well -mgt
#Archive = archiv/httpd/*access_log.*
#Archive = httpd/*access_log.*
#Archive = apache/*access.log.*.gz
#Archive = apache2/*access.log.*.gz
#Archive = apache2/*access_log.*.gz
#Archive = apache-ssl/*access.log.*.gz
#Archive = archiv/httpd/*access_log-*
#Archive = httpd/*access_log-*
#Archive = apache/*access.log-*.gz
#Archive = apache2/*access.log-*.gz
#Archive = apache2/*access_log-*.gz
#Archive = apache-ssl/*access.log-*.gz
Archive = nginx/*access.log.*.gz
Archive = nginx/*error.log.*.gz
# Expand the repeats (actually just removes them now)
*ExpandRepeats
# Keep only the lines in the proper date range...
*ApplyhttpDate
# vi: shiftwidth=3 tabstop=3 et
</code></pre></div></div>
<p>Enregistrez et quittez (: wq!) Ce fichier et modifiez /etc/logwatch/conf/services/nginx.conf:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp /etc/logwatch/conf/services/nginx.conf /etc/logwatch/conf/services/nginx.conf.org.bak
vi /etc/logwatch/conf/services/nginx.conf
</code></pre></div></div>
<p>Changez le nom de http en NGINX ou remplacez le fichier entier par le mien:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>###########################################################################
# Configuration file for NGINX filter
###########################################################################
Title = "NGINX"
# Which logfile group...
LogFile = NGINX
# Define the log file format
#
# This is now the same as the LogFormat parameter in the configuration file
# for httpd. Multiple instances of declared LogFormats in the httpd
# configuration file can be declared here by concatenating them with the
# '|' character. The default, shown below, includes the Combined Log Format,
# the Common Log Format, and the default SSL log format.
#$LogFormat = "%h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-Agent}i\"|%h %l %u %t \"%r\" %&gt;s %b|%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
# The following is supported for backwards compatibility, but deprecated:
# Define the log file format
#
# the only currently supported fields are:
# client_ip
# request
# http_rc
# bytes_transfered
# agent
#
#$HTTP_FIELDS = "client_ip ident userid timestamp request http_rc bytes_transfered referrer agent"
#$HTTP_FORMAT = "space space space brace quote space space quote quote"
# Define the field formats
#
# the only currently supported formats are:
# space = space delimited field
# quote = quoted ("..") space delimited field
# brace = braced ([..]) space delimited field
# Flag to ignore 4xx and 5xx error messages as possible hack attempts
#
# Set flag to 1 to enable ignore
# or set to 0 to disable
$HTTP_IGNORE_ERROR_HACKS = 0
# Ignore requests
# Note - will not do ANY processing, counts, etc... just skip it and go to
# the next entry in the log file.
# Note - The match will be case insensitive; e.g. /model/ == /MoDel/
# Examples:
# 1. Ignore all URLs starting with /model/ and ending with 1 to 10 digits
# $HTTP_IGNORE_URLS = ^/model/\d{1,10}$
#
# 2. Ignore all URLs starting with /model/ and ending with 1 to 10 digits and
# all URLS starting with /photographer and ending with 1 to 10 digits
# $HTTP_IGNORE_URLS = ^/model/\d{1,10}$|^/photographer/\d{1,10}$
# or simply:
# $HTTP_IGNORE_URLS = ^/(model|photographer)/\d{1,10}$
# To ignore a range of IP addresses completely from the log analysis,
# set $HTTP_IGNORE_IPS. For example, to ignore all local IP addresses:
#
# $HTTP_IGNORE_IPS = ^10\.|^172\.(1[6-9]|2[0-9]|3[01])\.|^192\.168\.|^127\.
#
# For more sophisticated ignore rules, you can define HTTP_IGNORE_EVAL
# to an arbitrary chunk of code.
# The default is not to filter anything:
$HTTP_IGNORE_EVAL = 0
# Example:
# $HTTP_IGNORE_EVAL = "($field{http_rc} == 401) &amp;&amp; ($field{client_ip}=~/^192\.168\./) &amp;&amp; ($field{url}=~m%^/protected1/%)"
# See the "scripts/services/http" script for other variables that can be tested.
# The variable $HTTP_USER_DISPLAY defines which user accesses are displayed.
# The default is not to display user accesses:
$HTTP_USER_DISPLAY = 0
# To display access failures:
# $HTTP_USER_DISPLAY = "$field{http_rc} &gt;= 400"
# To display all user accesses except "Unauthorized":
# $HTTP_USER_DISPLAY = "$field{http_rc} != 401"
# To raise the needed level of detail for one or more specific
# error codes to display a summary instead of listing each
# occurrence, set a variable like the following ones:
# Raise 403 codes to detail level High
#$http_rc_detail_rep_403 = 10
# Always show only summary for 404 codes
#$http_rc_detail_rep_404 = 20
# vi: shiftwidth=3 tabstop=3 et
</code></pre></div></div>
<p>Enregistrez et quittez le fichier (: wq!) Et désactivez les fichiers de configuration apache par défaut:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /usr/share/logwatch/default.conf/services
mv http-error.conf http-error.conf.bak &amp;&amp; mv http.conf http.conf.bak
</code></pre></div></div>
<p>Au moins, nous créons un cronjob pour envoyer le résultat de logwatch automatiquement:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab -e
</code></pre></div></div>
<p>Collez la ligne suivante:</p>
<p><code class="language-plaintext highlighter-rouge">@daily /usr/sbin/logwatch --output mail --mailto your@mail.com --format html --detail high --range yesterday &gt; /dev/null 2&gt;&amp;1</code></p>
<p>Enregistrez et quittez crontab et vérifiez si logwatch est correctement configuré:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/sbin/logwatch --output mail --mailto your@mail.com --format html --detail high --range yesterday
</code></pre></div></div>
<p>Vous devriez recevoir un email de logwatch qui ressemble à ceci:</p>
<p>image</p>
<p>A partir de maintenant, vous recevrez des mails quotidiens contenant votre résumé système.</p>
<p>Profitez de vos données personnelles sur votre Nextcloud-Server sécurisé et sécurisé!</p>
<h2 id="noubliez-pas-de-sauvegarder-votre-nextcloud">Noubliez pas de sauvegarder votre Nextcloud</h2>
<p>Retrouvez plus dinstructions ici: <a href="https://www.c-rieger.de/nextcloud-backup-and-restore/">Sauvegarde et restauration Nextcloud (en)</a></p>
<h2 id="update-nextcloud-lien-hs"><a href="/files/html/Update Nextcloud.htm">Update Nextcloud-Lien HS</a></h2>
</div>
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2020-01-20T00:00:00+01:00"><!-- start custom article footer snippet -->
<!-- end custom article footer snippet -->
<!--
<div align="right"><a type="application/rss+xml" href="/feed.xml" title="S'abonner"><i class="fa fa-rss fa-2x"></i></a>
&emsp;</div>
-->
</footer>
<div class="article__section-navigator clearfix"><div class="previous"><span>PRÉCÉDENT</span><a href="/2020/01/19/Portable-eeepc1001ha.html">Asus eeepc1001ha (noir) REV. 10/2020</a></div><div class="next"><span>SUIVANT</span><a href="/2020/02/08/grep-awk-sed.html">grep - awk - sed</a></div></div></div>
</div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
$(function() {
var $this ,$scroll;
var $articleContent = $('.js-article-content');
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
$scroll = $(scroll);
$articleContent.find('.highlight').each(function() {
$this = $(this);
$this.attr('data-lang', $this.find('code').attr('data-lang'));
});
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
$this = $(this);
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
});
$articleContent.on('click', '.anchor', function() {
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
});
});
});
})();
</script>
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
<!-- end custom main bottom snippet -->
</div>
</div></div></div></div>
</div><script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $body = $('body'), $window = $(window);
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
var activeCount = 0;
function modal(options) {
var $root = this, visible, onChange, hideWhenWindowScroll = false;
var scrollTop;
function setOptions(options) {
var _options = options || {};
visible = _options.initialVisible === undefined ? false : show;
onChange = _options.onChange;
hideWhenWindowScroll = _options.hideWhenWindowScroll;
}
function init() {
setState(visible);
}
function setState(isShow) {
if (isShow === visible) {
return;
}
visible = isShow;
if (visible) {
activeCount++;
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
$root.addClass('modal--show');
$pageMain.scrollTop(scrollTop);
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
$window.on('keyup', handleKeyup);
} else {
activeCount > 0 && activeCount--;
$root.removeClass('modal--show');
$window.scrollTop(scrollTop);
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
$window.off('keyup', handleKeyup);
}
onChange && onChange(visible);
}
function show() {
setState(true);
}
function hide() {
setState(false);
}
function handleKeyup(e) {
// Char Code: 27 ESC
if (e.which === 27) {
hide();
}
}
setOptions(options);
init();
return {
show: show,
hide: hide,
$el: $root
};
}
$.fn.modal = modal;
});
})();
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
(function () {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
// search panel
var search = (window.search || (window.search = {}));
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
true : window.useDefaultSearchBox ;
var $searchModal = $('.js-page-search-modal');
var $searchToggle = $('.js-search-toggle');
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
var modalVisible = false;
search.searchModal = searchModal;
var $searchBox = null;
var $searchInput = null;
var $searchClear = null;
function getModalVisible() {
return modalVisible;
}
search.getModalVisible = getModalVisible;
function handleModalChange(visible) {
modalVisible = visible;
if (visible) {
search.onShow && search.onShow();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
} else {
search.onShow && search.onHide();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
setTimeout(function() {
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
search.clear && search.clear();
window.pageAsideAffix && window.pageAsideAffix.refresh();
}, 400);
}
}
$searchToggle.on('click', function() {
modalVisible ? searchModal.hide() : searchModal.show();
});
// Char Code: 83 S, 191 /
$(window).on('keyup', function(e) {
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
modalVisible || searchModal.show();
}
});
if (useDefaultSearchBox) {
$searchBox = $('.js-search-box');
$searchInput = $searchBox.children('input');
$searchClear = $searchBox.children('.js-icon-clear');
search.getSearchInput = function() {
return $searchInput.get(0);
};
search.getVal = function() {
return $searchInput.val();
};
search.setVal = function(val) {
$searchInput.val(val);
};
$searchInput.on('focus', function() {
$(this).addClass('focus');
});
$searchInput.on('blur', function() {
$(this).removeClass('focus');
});
$searchInput.on('input', window.throttle(function() {
var val = $(this).val();
if (val === '' || typeof val !== 'string') {
search.clear && search.clear();
} else {
$searchBox.addClass('not-empty');
search.onInputNotEmpty && search.onInputNotEmpty(val);
}
}, 400));
$searchClear.on('click', function() {
$searchInput.val(''); $searchBox.removeClass('not-empty');
search.clear && search.clear();
});
}
});
})();
</script><div class="search search--dark">
<div class="main">
<div class="search__header">Recherche</div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div>
</div>
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
Annuler</button>
</div>
<div id="results-container" class="search-result js-search-result"></div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
noResultsText: '<p>Aucun résultat!</p>',
json: '/search.json',
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a>&nbsp;(Création {create})</li>'
})
</script>
</div></div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function scrollToAnchor(anchor, duration, callback) {
var $root = this;
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
callback && callback();
});
}
$.fn.scrollToAnchor = scrollToAnchor;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function affix(options) {
var $root = this, $window = $(window), $scrollTarget, $scroll,
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
hasInit = false, curState;
function setOptions(options) {
var _options = options || {};
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroll && (scroll = _options.scroll);
_options.disabled !== undefined && (disabled = _options.disabled);
$scrollTarget = $(scrollTarget);
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
$scroll = $(scroll);
}
function preCalc() {
top();
rootHeight = $root.outerHeight();
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
rootLeft = $root.offset().left;
}
function calc(needPreCalc) {
needPreCalc && preCalc();
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
rootBottomTop = scrollBottom - rootTop;
}
function top() {
if (curState !== 'top') {
$root.removeClass('fixed').css({
left: 0,
top: 0
});
curState = 'top';
}
}
function fixed() {
if (curState !== 'fixed') {
$root.addClass('fixed').css({
left: rootLeft + 'px',
top: 0
});
curState = 'fixed';
}
}
function bottom() {
if (curState !== 'bottom') {
$root.removeClass('fixed').css({
left: 0,
top: rootBottomTop + 'px'
});
curState = 'bottom';
}
}
function setState() {
var scrollTop = $scrollTarget.scrollTop();
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
fixed();
} else if (scrollTop < rootTop) {
top();
} else {
bottom();
}
}
function init() {
if(!hasInit) {
var interval, timeout;
calc(true); setState();
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState();
});
$window.on('resize', function() {
disabled || (calc(true), setState());
});
hasInit = true;
}
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions,
refresh: function() {
calc(true, { animation: false }); setState();
}
};
}
$.fn.affix = affix;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function toc(options) {
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
function setOptions(options) {
var _options = options || {};
_options.selectors && (selectors = _options.selectors);
_options.container && (container = _options.container);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroller && (scroller = _options.scroller);
_options.disabled !== undefined && (disabled = _options.disabled);
$headings = $(container).find(selectors).filter('[id]');
$scrollTarget = $(scrollTarget);
$scroller = $(scroller);
}
function calc() {
headingsPos = [];
$headings.each(function() {
headingsPos.push(Math.floor($(this).position().top));
});
}
function setState(element, disabled) {
var scrollTop = $scrollTarget.scrollTop(), i;
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
if (element) {
$activeCur = element;
} else {
for (i = 0; i < headingsPos.length; i++) {
if (scrollTop >= headingsPos[i]) {
$activeCur = $tocLi.eq(i);
} else {
$activeCur || ($activeCur = $tocLi.eq(i));
break;
}
}
}
$activeLast && $activeLast.removeClass('active');
($activeLast = $activeCur).addClass('active');
}
function render() {
if(!hasRendered) {
$root.append($tocUl);
$headings.each(function() {
var $this = $(this);
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
});
$tocLi = $tocUl.children('li');
$tocUl.on('click', 'a', function(e) {
e.preventDefault();
var $this = $(this);
scrolling = true;
setState($this.parent());
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
scrolling = false;
});
});
}
hasRendered = true;
}
function init() {
var interval, timeout;
if(!hasInit) {
render(); calc(); setState(null, scrolling);
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState(null, scrolling);
});
$window.on('resize', window.throttle(function() {
if (!disabled) {
render(); calc(); setState(null, scrolling);
}
}, 100));
}
hasInit = true;
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions
};
}
$.fn.toc = toc;
});
})();
/*(function () {
})();*/
</script><script>
/* toc must before affix, since affix need to konw toc' height. */(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window);
var $articleContent = $('.js-article-content');
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
var toc;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
function disabled() {
return $col2.css('display') === 'none' || !hasToc;
}
tocDisabled = disabled();
toc = $tocRoot.toc({
selectors: TOC_SELECTOR,
container: $articleContent,
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
tocDisabled = disabled();
toc && toc.setOptions({
disabled: tocDisabled
});
}, 100));
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window), $pageFooter = $('.js-page-footer');
var $pageAside = $('.js-page-aside');
var affix;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
affix = $pageAside.affix({
offsetBottom: $pageFooter.outerHeight(),
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
scroll: hasSidebar ? $('.js-page-main').children() : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
affix && affix.setOptions({
disabled: tocDisabled
});
}, 100));
window.pageAsideAffix = affix;
});
})();
</script><!---->
</div>
<script>(function () {
var $root = document.getElementsByClassName('root')[0];
if (window.hasEvent('touchstart')) {
$root.dataset.isTouch = true;
document.addEventListener('touchstart', function(){}, false);
}
})();
</script>
</body>
</html>