yannstatic/static/2018/12/21/vps591606_debian_9_yunohost_cinay.xyz.html

3851 lines
278 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>vps591606 Debian 9 - Yunohost - cinay.xyz (INACTIF) - YannStatic</title>
<meta name="description" content="Yunohost Debian Stretch cinay.xyz">
<link rel="canonical" href="https://static.rnmkcy.eu/2018/12/21/vps591606_debian_9_yunohost_cinay.xyz.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">
2024-11-28 11:42:23 +01:00
<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="/syntaxe-markdown.html">Aide</a></li></ul>
2024-10-31 20:18:37 +01:00
</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;">vps591606 Debian 9 - Yunohost - cinay.xyz (INACTIF)</h1></header></div><meta itemprop="headline" content="vps591606 Debian 9 - Yunohost - cinay.xyz (INACTIF)"><div class="article__info clearfix"><ul class="left-col menu"><li>
2024-11-08 14:10:33 +01:00
<a class="button button--secondary button--pill button--sm" style="color:#00FFFF" href="/archive.html?tag=yunohost">yunohost</a>
2024-10-31 20:18:37 +01:00
</li></ul><ul class="right-col menu"><li>
<i class="far fa-calendar-alt"></i>&nbsp;<span title="Création" style="color:#FF00FF">21&nbsp;déc.&nbsp;&nbsp;2018</span>
<span title="Modification" style="color:#00FF7F">21&nbsp;juil.&nbsp;2020</span></li></ul></div><meta itemprop="datePublished" content="2020-07-21T00:00:00+02:00">
<meta itemprop="keywords" content="yunohost"><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="yunohost-debian-stretch-cinayxyz">Yunohost Debian Stretch cinay.xyz</h2>
<h3 id="vps-kvm-ovh">VPS-KVM OVH</h3>
<p><img src="/images/OVH-320px-Logo.png" alt="" width="100px" /><br />
VPS 2018 SSD 3</p>
<ul>
<li>2 vCores</li>
<li>8Go Ram</li>
<li>80Go SSD</li>
</ul>
<p>Livraison : vps591606 51.75.120.106</p>
<ul>
<li>Domaine : cinay.xyz</li>
<li>IPv4 du serveur : 51.75.120.106</li>
<li>IPv6 du serveur : 2001:41d0:0305:2100:0:0:0:4dc0 (2001:41d0:305:2100::4dc0)</li>
<li>IPV6 gateway : 2001:41d0:0305:2100:0:0:0:1 (2001:41d0:305:2100::1)</li>
</ul>
<h3 id="debian-stretch">Debian Stretch</h3>
<p><img src="/images/debian-stretch-logo.png" alt="Debian 9" /></p>
<p>Connexion SSH sur “VPS 2018 SSD 3 (2 vCores/8GoRam/80GoSSD)”</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh root@51.75.120.106
</code></pre></div></div>
<p><strong>Modification du réseau, ajout IPV6</strong><br />
Sur le VPS OVH il faut désactiver linitialisation réseau par le cloud</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
</code></pre></div></div>
<p>Création du fichier <strong>/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg</strong> en mode su</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "network: {config: disabled}" &gt; /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
</code></pre></div></div>
<p>Modifier le fichier <strong>/etc/network/interfaces</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto ens3
iface ens3 inet dhcp
iface ens3 inet6 static
address 2001:41d0:0305:2100:0:0:0:4dc0
netmask 128
post-up /sbin/ip -6 route add 2001:41d0:0305:2100:0:0:0:1 dev ens3
post-up /sbin/ip -6 route add default via 2001:41d0:0305:2100:0:0:0:1 dev ens3
pre-down /sbin/ip -6 route del default via 2001:41d0:0305:2100:0:0:0:1 dev ens3
pre-down /sbin/ip -6 route del 2001:41d0:0305:2100:0:0:0:1 dev ens3
</code></pre></div></div>
<p><strong>Mise à jour de la distribution debian stretch</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt update &amp;&amp; apt -y upgrade
</code></pre></div></div>
<blockquote>
<p>Redémarrer la machine <code class="language-plaintext highlighter-rouge">systemctl reboot</code> pour la prise en compte des modifications du réseau</p>
</blockquote>
<p>Connexion SSH sur “VPS 2018 SSD 3 (2 vCores/8GoRam/80GoSSD)”</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh root@51.75.120.106
</code></pre></div></div>
<p>Vérifier le réseau <code class="language-plaintext highlighter-rouge">ip addr</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens3: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether fa:16:3e:07:c2:34 brd ff:ff:ff:ff:ff:ff
inet 51.75.120.106/32 brd 51.75.120.106 scope global ens3
valid_lft forever preferred_lft forever
inet6 2001:41d0:305:2100::4dc0/128 scope global
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fe07:c234/64 scope link
valid_lft forever preferred_lft forever
</code></pre></div></div>
<h2 id="yunohost">Yunohost</h2>
<p><img src="/images/yunohost.png" alt="Yunohost" width="50px" /></p>
<h3 id="installation-yunohost">Installation Yunohost</h3>
<p>Lancer le bash et patienter</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bash &lt;(wget -q -O- https://install.yunohost.org/)
</code></pre></div></div>
<p>Valider la “post-installation” ou lancer</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost tools postinstall
</code></pre></div></div>
<p>Main domain: cinay.xyz <br />
Mot de passe administrateur</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Success! YunoHost has been configured
Warning: The post-install is finished but YunoHost needs at least one user to work correctly, you should add one using 'yunohost user create' or the admin interface.
[INFO] Installation logs are available in /var/log/yunohost-installation_20181203_070221.log
[ OK ] YunoHost installation completed !
</code></pre></div></div>
<h3 id="créer-un-utilisateur">Créer un utilisateur</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost user create yannick
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Mot de passe d'administration :
Prénom : yannick
Nom : meunier
Adresse courriel : yannick@cinay.xyz
Mot de passe :
Confirmez : mot de passe :
Création du répertoire « /home/yannick ».
Succès ! La configuration de SSOwat a été générée
Succès ! L'utilisateur a été créé
fullname: yannick meunier
mail: yannick@cinay.xyz
username: yannick
</code></pre></div></div>
<h3 id="installation-des-certificats">Installation des certificats</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain cert-install
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Info: Now attempting install of certificate for domain cinay.xyz!
Succès ! La configuration de SSOwat a été générée
Succès ! La configuration a été mise à jour pour le service « dnsmasq »
Info: Parsing account key...
Info: Parsing CSR...
Info: Registering account...
Info: Registered!
Info: Verifying cinay.xyz...
Info: cinay.xyz verified!
Info: Signing certificate...
Info: Certificate signed!
Succès ! Installation avec succès dun certificat Lets Encrypt pour le domaine cinay.xyz !
</code></pre></div></div>
<h3 id="administration-yunohost">Administration yunohost</h3>
<p>Connexion administrateur yunohost <a href="https://cinay.xyz/yunohost/admin">https://cinay.xyz/yunohost/admin</a><br />
Vérifier le status des services <a href="https://cinay.xyz/yunohost/admin/#/services">https://cinay.xyz/yunohost/admin/#/services</a><br />
Récupérer les paramètres DNS du domaine cinay.xyz <a href="https://cinay.xyz/yunohost/admin/#/domains/cinay.xyz/dns">https://cinay.xyz/yunohost/admin/#/domains/cinay.xyz/dns</a></p>
<h3 id="administration-ovh-dns-et-vps">Administration OVH (DNS et VPS)</h3>
<p>Se connecter sur le manager OVH</p>
<p>Modifier le reverse DNS du VPS vps591606.ovh.net (IPV4 er IPV6) : cinay.xyz<br />
Modifier la configuration DNS du domaine cinay.xyz</p>
<p><img src="/images/dns-logo.png" alt="DNS" /></p>
<p>Se connecter en administrateur sur le site <strong>cinay.xyz</strong><br />
Domaines → cinay.xyz → Configuration DNS # pour récupérer les paramètres<br />
Modifier la DNS du domaine cinay.xyz :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$TTL 3600
@ IN SOA dns112.ovh.net. tech.ovh.net. (2018092426 86400 3600 3600000 300)
3600 IN NS dns112.ovh.net.
3600 IN NS ns112.ovh.net.
3600 IN MX 10 cinay.xyz.
3600 IN A 51.75.120.106
3600 IN AAAA 2001:41d0:305:2100::4dc0
600 IN TXT "v=spf1 a mx ip4:51.75.120.106 ip6:2001:41d0:305:2100::4dc0 -all"
* 3600 IN CNAME cinay.xyz.
_dmarc IN TXT ( "v=DMARC1; p=none;" )
_xmpp-client._tcp 3600 IN SRV 0 5 5222 cinay.xyz.
_xmpp-server._tcp 3600 IN SRV 0 5 5269 cinay.xyz.
mail._domainkey 3600 IN TXT ( "v=DKIM1; k=rsa; h=sha256; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOltTHam7WsBs1Fn26v7hSqe4bkNsruffIpinULglGcLHR8H0Cbks1jPuAZKuKLH1J7KxwelJ9F17mNqCuVDyPwGx1qLT8aEs3vD6L8tn9Aow1b2hEr2HQR6B6Ad90QYliI1BIVjrTjCpJyWYv3PUNow4QnUw/UhxX2bEK19apUwIDAQAB" )
muc 3600 IN CNAME cinay.xyz.
pubsub 3600 IN CNAME cinay.xyz.
vjud 3600 IN CNAME cinay.xyz.
</code></pre></div></div>
<h3 id="sécurité">Sécurité</h3>
<h4 id="openssh-avec-clés">OpenSSH avec clés</h4>
<p><img src="/images/ssh_logo1.png" alt="OpenSSH" /></p>
<p><strong>Créer un utilisateur debian</strong><br />
Il faut un utilisateur debian non ldap pour les connexions ssh</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>adduser debadm # création du home et saisie mot de passe
</code></pre></div></div>
<p>Visudo pour les accès root via utilisateur debadm</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "debadm ALL=(ALL) NOPASSWD: ALL" &gt;&gt; /etc/sudoers
</code></pre></div></div>
<p><strong>Poste local</strong><br />
Génération dune paire de clés</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -f ~/.ssh/kvm-vps591606 -t ed25519 -o -a 100
</code></pre></div></div>
<p>Le déploiement de la clé publiques .pub</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-copy-id -i ~/.ssh/kvm-vps591606.pub debadm@51.75.120.106
</code></pre></div></div>
<p><strong>Serveur distant</strong></p>
<p>Se connecter au serveur distant depuis le poste local avec utilisateur debian</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh debadm@cinay.xyz
</code></pre></div></div>
<p>La clé publique est ajoutée au fichier distant <strong>/home/debadm/.ssh/authorized_keys</strong> du serveur <br />
Autre possibilité :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir /home/debadm/.ssh # créer un dossier .ssh
nano /home/debadm/.ssh/authorized_keys # Coller le contenu de la clé publique kvm-vps591606.pub
chmod 600 /home/debadm/.ssh/authorized_keys # droits utilisateur
</code></pre></div></div>
<p><strong>Utiliser la clé publique</strong></p>
<p>Fichier <strong>/etc/ssh/sshd_config</strong> sur le serveur distant, liste des paramètres qui sont modifiés</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Port 55031
PermitRootLogin no
PasswordAuthentication no
</code></pre></div></div>
<blockquote>
<p>On peut également modifier le port de connexion SSH<br />
Exemple remplacer port 22 par port 55031 :<br />
<code class="language-plaintext highlighter-rouge">Port 55031</code> # dans le fichier <strong>/etc/ssh/sshd_config</strong><br />
NE PAS OUBLIER DE MODIFIER LE PAREFEU (FIREWALL) YUNOHOST :<br />
<code class="language-plaintext highlighter-rouge">yunohost firewall disallow TCP 22</code> # désactiver le port 22<br />
<code class="language-plaintext highlighter-rouge">yunohost firewall allow TCP 55031</code> # activer le port 55031</p>
</blockquote>
<p>Recharger le serveur ssh</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart sshd
</code></pre></div></div>
<p><strong>Test de la connexion ssh par clé depuis le poste local</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -i ~/.ssh/kvm-vps591606 debadm@51.75.120.106 # port 22
ssh -p 55031 -i ~/.ssh/kvm-vps591606 debadm@51.75.120.106 # port 55031
ssh -p 55031 -i ~/.ssh/kvm-vps591606 debadm@cinay.xyz # port 55031 et DNS OK/Domaine
</code></pre></div></div>
<p><strong>Affichage à la connexion ssh</strong></p>
<p>Exécuter un fichier <em>utilisateur</em> nommé <strong>$HOME/.ssh/rc</strong> si <em>présent (NON PRESENT)</em><br />
Pour <em>tous les utilisateurs</em> exécuter un fichier nommé <strong>/etc/ssh/sshrc</strong> si <em>présent (NON PRESENT)</em><br />
Installer les utilitaires <em>curl jq figlet tmux</em></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install curl jq figlet
sudo apt install tmux p7zip # outils supplémentaires
</code></pre></div></div>
<p>Créer le fichier <strong>~/ssh_rc_bash</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/bash
#clear
PROCCOUNT=`ps -Afl | wc -l` # nombre de lignes
PROCCOUNT=`expr $PROCCOUNT - 5` # on ote les non concernées
GROUPZ=`users`
ipinfo=$(curl -s ipinfo.io) # info localisation format json
publicip=$(echo $ipinfo | jq -r '.ip') # extraction des données , installer préalablement "jq"
ville=$(echo $ipinfo | jq -r '.city')
pays=$(echo $ipinfo | jq -r '.country')
cpuname=`cat /proc/cpuinfo |grep 'model name' | cut -d: -f2 | sed -n 1p`
iplink=`ip link show |grep -m 1 "2:" | awk '{print $2}' | cut -d: -f1`
echo "\033[0m\033[1;31m"
figlet "`hostname --fqdn`"
echo "\033[0m
\033[1;35m \033[1;37mHostname \033[1;35m= \033[1;32m`hostname`
\033[1;35m \033[1;37mWired IpV4 \033[1;35m= \033[1;32m`ip addr show $iplink | grep 'inet\b' | awk '{print $2}' | cut -d/ -f1`
\033[1;35m \033[1;37mWired IpV6 \033[1;35m= \033[1;32m`ip addr show $iplink | grep -E 'inet6' |grep -E 'scope link' | awk '{print $2}' | cut -d/ -f1`
\033[1;35m \033[1;37mKernel \033[1;35m= \033[1;32m`uname -r`
\033[1;35m \033[1;37mDebian \033[1;35m= \033[1;32m`cat /etc/debian_version`
\033[1;35m \033[1;37mUptime \033[1;35m= \033[1;32m`uptime | sed 's/.*up ([^,]*), .*/1/' | sed -e 's/^[ \t]*//'`
\033[1;35m \033[1;37mCPU \033[1;35m= \033[1;32m`echo $cpuname`
\033[1;35m \033[1;37mMemory Use \033[1;35m= \033[1;32m`free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }'`
\033[1;35m \033[1;37mUsername \033[1;35m= \033[1;32m`whoami`
\033[1;35m \033[1;37mSessions \033[1;35m= \033[1;32m`who | grep $USER | wc -l`
\033[1;35m \033[1;37mPublic IpV4 \033[1;35m= \033[1;32m`echo $publicip`
\033[1;35m \033[1;37mPublic IpV6 \033[1;35m= \033[1;32m`ip addr show $iplink | grep -m 1 'inet6\b' | awk '{print $2}' | cut -d/ -f1`
\033[0m"
df -h /
#curl fr.wttr.in/$ville?0
</code></pre></div></div>
<p>Le rendre exécutable</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x ~/ssh_rc_bash
</code></pre></div></div>
<p>Recréer motd</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm /etc/motd &amp;&amp; sudo nano /etc/motd
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ___ ___ _ __ __ __
__ __ _ __ ___| __|/ _ \/ | / / / \ / /
\ V /| '_ \(_-&lt;|__ \\_, /| |/ _ \| () |/ _ \
\_/ | .__//__/|___/ /_/ |_|\___/ \__/ \___/
|_|
__ (_) _ _ __ _ _ _ __ __ _ _ ___
/ _|| || ' \ / _` || || | _ \ \ /| || ||_ /
\__||_||_||_|\__,_| \_, |(_)/_\_\ \_, |/__|
|__/ |__/
</code></pre></div></div>
<p>Déconnexion puis connexion</p>
<h4 id="désactivation-de-lapi-yunohost">Désactivation de lAPI YunoHost</h4>
<p>YunoHost est administrable via une API HTTP, servie sur le port 6787 par défaut (seulement sur localhost). Elle permet dadministrer une grande partie de votre serveur, et peut donc être utilisée à des fins malveillantes. La meilleure chose à faire si vous êtes habitués aux lignes de commande est de désactiver le service yunohost-api, et utiliser la ligne de commande en SSH.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl disable yunohost-api
sudo systemctl stop yunohost-api
</code></pre></div></div>
<h2 id="applications-yunohost">Applications Yunohost</h2>
<h3 id="nextcloud">Nextcloud</h3>
<p><img src="/images/nextcloud_logo.png" alt="Nextcloud" /><br />
Installer <strong>Nextcloud</strong> avec ladministrateur web yunohost <br />
<em>Accéder au dossier personnel des utilisateurs depuis Nextcloud</em></p>
<h3 id="transmission">Transmission</h3>
<p><img src="/images/transmission-logo.png" alt="Transmission" /><br />
Installer <strong>Transmission</strong> avec ladministrateur web yunohost</p>
<h3 id="tiny-tiny-rss">Tiny Tiny RSS</h3>
<p><img src="/images/ttrss-logo.png" alt="Tiny Tiny RSS" /><br />
Installer <strong>Tiny Tiny RSS</strong> avec ladministrateur web yunohost <br />
Thèmes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
git clone https://github.com/levito/tt-rss-feedly-theme.git
cp -r tt-rss-feedly-theme/feedly* /var/www/ttrss/themes.local/
</code></pre></div></div>
<h3 id="gitea-publique-giteacinayxyz">Gitea (publique gitea.cinay.xyz)</h3>
<p><img src="/images/gitea-logo.png" alt="Gitea" /></p>
<ol>
<li>Ajout domaine <strong>gitea.cinay.xz</strong></li>
<li>Certificats Lets Encrypt pour le domaine</li>
<li>Installer lapplication <strong>Gitea</strong>
<ul>
<li>domaine : gitea.cinay.xyz</li>
<li>Chemin : /</li>
<li>Administrateur : yannick</li>
<li>Site publique : Oui</li>
</ul>
</li>
</ol>
<p><img src="/images/gitea-web.png" alt="gitea-web" width="400" /><br />
<a href="https://gitea.cinay.xyz/">https://gitea.cinay.xyz/</a></p>
<h3 id="calibre-web-publique-calibrecinayxyz">Calibre-Web (publique calibre.cinay.xyz)</h3>
<p><img src="/images/Calibre_logo.png" alt="Calibre-web" /></p>
<ol>
<li>Ajout domaine <strong>calibre.cinay.xz</strong></li>
<li>Certificats Lets Encrypt pour le domaine</li>
<li>Installer lapplication <strong>Calibre-web</strong><br />
<img src="/images/calibre-web-ynh.png" alt="calibre-web" width="300" /></li>
</ol>
<p>Emplacement de la base de donnée Calibre : <strong>/home/yunohost.multimedia/share/eBook/</strong><br />
Copie dossier CalibreTechnique du serveur backup xoyaz.xyz → cinay.xyz</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
rsync -avz -e "ssh -p 55036 -i .ssh/OVZ-STORAGE-128 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress usernl@5.2.79.107:/home/usernl/backup/CalibreTechnique/* /home/yunohost.multimedia/share/eBook/
</code></pre></div></div>
<p>En mode admin , il faut redémarrer calibre-web<br />
Automatiser la synchronisation des dossiers</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab -e # ajouter la ligne suivante en fin de fichier
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Synchroniser le dossier "CalibreTechnique" entre le serveur de backup distant xoyaz.xyz et le serveur local cinay.xyz
15 01 * * * /usr/bin/rsync -avz -e "ssh -p 55036 -i .ssh/OVZ-STORAGE-128 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress usernl@5.2.79.107:/home/usernl/backup/CalibreTechnique/* /home/yunohost.multimedia/share/eBook/
</code></pre></div></div>
<p><img src="/images/calibre-web.png" alt="calibre-web" width="400" /><br />
<a href="https://calibre.cinay.xz">https://calibre.cinay.xz</a></p>
<h3 id="dokuwiki">Dokuwiki</h3>
<p><img src="/images/dokuwiki-logo.png" alt="Texte alternatif" /><br />
Installer <strong>Dokuwiki</strong> avec ladministrateur web yunohost</p>
<p><strong>En cas de problème</strong></p>
<p>Le point le plus important et la prise en charge LDAP , le plugin <strong>LDAP Auth Plugin</strong> doit être actif (cas de transfert de dokuwiki ou après une mise à jour , perte de lauthentification LDAP !!!)<br />
La configuration spécifique à LDAP dans le fichier <strong>/var/www/dokuwiki/conf/dokuwiki.php</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/* Authentication Settings */
$conf['useacl'] = 1; //Use Access Control Lists to restrict access?
$conf['openregister']= 0;
$conf['autopasswd'] = 1; //autogenerate passwords and email them to user
$conf['authtype'] = 'authldap'; //which authentication backend should be used
$conf['passcrypt'] = 'sha1'; //Used crypt method (smd5,md5,sha1,ssha,crypt,mysql,my411)
$conf['defaultgroup']= 'user'; //Default groups new Users are added to
$conf['superuser'] = 'yannick'; //The admin can be user or @group or comma separated list user1,@group1,user2
$conf['manager'] = 'yannick'; //The manager can be user or @group or comma separated list user1,@group1,user2
$conf['profileconfirm'] = 1; //Require current password to confirm changes to user profile
$conf['rememberme'] = 1; //Enable/disable remember me on login
$conf['disableactions'] = ''; //comma separated list of actions to disable
$conf['auth_security_timeout'] = 900; //time (seconds) auth data is considered valid, set to 0 to recheck on every page view
$conf['securecookie'] = 1; //never send HTTPS cookies via HTTP
$conf['remote'] = 0; //Enable/disable remote interfaces
$conf['remoteuser'] = '!!not set !!'; //user/groups that have access to remote interface (comma separated)
/* LDAP Yunohost config */
$conf['plugin']['authldap']['server'] = 'localhost';
$conf['plugin']['authldap']['port'] = 389;
$conf['plugin']['authldap']['version'] = 3;
$conf['plugin']['authldap']['usertree'] = 'ou=users,dc=yunohost,dc=org';
$conf['plugin']['authldap']['userfilter'] = '(&amp;(uid=%{user})(objectClass=posixAccount))';
# no groups
#$conf['plugin']['authldap']['grouptree'] = 'ou=Group, dc=server, dc=tld';
#$conf['plugin']['authldap']['groupfilter'] = '(&amp;(objectClass=posixGroup)(|(gidNumber=%{gid})(memberUID=%{user})))';
</code></pre></div></div>
<p><strong>Structure et droits des dossiers dokuwiki</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@cinay:/home/debadm# ls -la /var/www/dokuwiki/
total 124
drwxr-xr-x 9 root root 4096 Nov 6 15:56 .
drwxr-xr-x 7 root root 4096 Dec 3 09:30 ..
drwxr-xr-x 2 root root 4096 May 3 2018 bin
drwxr-xr-x 2 dokuwiki root 4096 Nov 6 15:57 conf
-rw-r--r-- 1 root root 18092 May 3 2018 COPYING
drwxr-x--- 12 dokuwiki root 4096 Nov 6 15:56 data
drwxr-xr-x 2 root root 12288 Sep 5 07:21 doc
-rw-r--r-- 1 root root 3547 Nov 6 15:56 doku.php
-rw-r--r-- 1 root root 19141 May 3 2018 feed.php
-rw-r--r-- 1 root root 1684 May 3 2018 .htaccess.dist
drwxr-xr-x 9 dokuwiki root 4096 Nov 6 15:56 inc
-rw-r--r-- 1 root root 2097 May 3 2018 index.php
-rw-r--r-- 1 root root 19233 May 3 2018 install.php
drwxr-xr-x 8 root root 4096 May 3 2018 lib
-rw-r--r-- 1 root root 306 May 3 2018 README
drwxr-xr-x 12 root root 4096 May 3 2018 vendor
-rw-r--r-- 1 root root 21 May 3 2018 VERSION
</code></pre></div></div>
<h3 id="cartographie-publique-mapcinayxyz">Cartographie (publique map.cinay.xyz)</h3>
<p><img src="/images/map.png" alt="Cartographie" width="100px" /></p>
<p><strong>Yunohost mode administration web</strong></p>
<p>créer le domaine <strong>map.cinay.xyz</strong> puis les certificats <strong>Lets Encrypt</strong><br />
Installation de lapplication “Multi webapp for YunoHost” sur le domaine <strong>map.cinay.xyz</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/multi_webapp_ynh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WARNING! Installing 3rd party applications may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. Are you willing to take that risk? [Y/N] : Y
Available domains:
- cinay.xyz
- map.cinay.xyz
- blog.cinay.xyz
- liens.cinay.xyz
- static.cinay.xyz
Choose a domain for your Webapp (default: cinay.xyz): map.cinay.xyz
Choose a path for your Webapp (default: /site): /
Available users:
- yannick
Choose the YunoHost user: yannick
Create a database? [yes | no] (default: no):
Is it a public website ? [yes | no] (default: no): yes
Info: [....................] &gt; Retrieve arguments from the manifest
Info: [#...................] &gt; Check if the app can be installed
Info: [##..................] &gt; Store settings from manifest
Info: [#####...............] &gt; Setup SSOwat
Info: [######..............] &gt; Create final path
Info: The directory /var/www/webapp_yannick already exist, do not recreate it.
Info: [#######.............] &gt; Create a dedicated user
Info: [##########..........] &gt; Configure php-fpm
Warning: Reload the service php7.0-fpm
Warning: Reload the service nginx
Info: [###########.........] &gt; Configure nginx
Info: [############........] &gt; Reload nginx
Info: [####################] &gt; Installation completed
Success! The SSOwat configuration has been generated
Success! Installation complete
</code></pre></div></div>
<p>Le dossier par défaut de “Multi webapp for YunoHost” <strong>/var/www/webapp_yannick/map.cinay.xyz_/</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm -r /var/www/webapp_yannick/map.cinay.xyz_/ # on supprime le dossier par défaut
sudo ln -s /srv/osm-new /var/www/webapp_yannick/map.cinay.xyz_ # créer le lien
</code></pre></div></div>
<blockquote>
<p>Changer létiquette par “Cartes” en utilisant ladministration web “Applications”</p>
</blockquote>
<p><strong>Synchronisation locale des fichiers gpx</strong></p>
<p>Les fichiers gpx du dossier <strong>/srv/osm-new/file</strong> ne peuvent pas être utilisés par nextcloud et map pour une question de droits <br />
Pour une utilisation par une application nextcloud dans le dossier <strong>/home/yannick/gpx</strong> on va le synchroniser avec le dossier <strong>/srv/osm-new/file/</strong> par lsyncd</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
apt install lsyncd # installation
systemctl stop lsyncd # arrêt du service pour modifier la configuration
mkdir /var/log/lsyncd
touch /var/log/lsyncd/lsyncd.{log,status}
# Configuration file goes on /etc/lsyncd:
mkdir /etc/lsyncd
# le fichier de configuration
echo '
settings = {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status"
}
sync {
default.rsync,
source = "/srv/osm-new/file/",
target = "/home/yannick/gpx",
}
' &gt; /etc/lsyncd/lsyncd.conf.lua
# lancement du service
systemctl restart lsyncd
</code></pre></div></div>
<p>Vue du fichier lsyncd.log</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Tue Dec 24 08:14:12 2019 Normal: recursive startup rsync: /srv/osm-new/file/ -&gt; /home/yannick/gpx/
Tue Dec 24 08:14:14 2019 Normal: Startup of "/srv/osm-new/file/" finished.
</code></pre></div></div>
<p>Le contenu du dossier /home/yannick/gpx est synchronisé automatiquement avec le dossier /srv/osm-new/file/</p>
<blockquote>
<p><strong>IMPORTANT</strong> : Cette synchronisation est imposée pour lutilisation dune application nextcloud nommée <strong>gpxpod</strong></p>
</blockquote>
<font color="red">L'application <b>gpxpod</b> ne sait pas traiter les noms de fichiers avec des espaces</font>
<p>, il faut exécuter dans le dossier <strong>/home/yannick/gpx</strong> , un bash <code class="language-plaintext highlighter-rouge">./remplacer-les-espaces-par_dans-les-noms-de-fichier.sh
</code> en mode su</p>
<font color="green"><b>LE PROBLEME EST RESOLU (DECEMBRE 2019)</b></font>
<p><img src="/images/map-web.png" alt="Cartographie" width="400px" /><br />
<a href="https://map.cinay.xyz/">https://map.cinay.xyz/</a></p>
<h3 id="shaarli-publique-shaarlicinayxyz">Shaarli (publique shaarli.cinay.xyz)</h3>
<p><img src="/images/shaarli_logo.png" alt="image" width="50px" /><br />
<em>Voulez-vous partager les liens que vous découvrez ? Shaarli est un gestionnaire de signets minimaliste et un service de partage de liens que vous pouvez installer sur votre propre serveur. Il est conçu pour être personnel (monoposte), rapide et pratique.</em></p>
<ol>
<li>Ajout domaine <strong>shaarli.cinay.xz</strong></li>
<li>Certificats Lets Encrypt pour le domaine</li>
<li>Installer lapplication <strong>shaarli</strong>
<ul>
<li>domaine : shaarli.cinay.xyz</li>
<li>Chemin : /</li>
<li>Site publique : Oui</li>
</ul>
</li>
</ol>
<blockquote>
<p><strong>ATTENTION!!!</strong> PROBLEMES+
de droits et dinstallation</p>
</blockquote>
<p>En raison des problèmes évoqués, voici la procédure à suivre :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm -r /var/www/shaarli # suppression appli web shaarli installée par yunohost
</code></pre></div></div>
<p><strong>Réinstaller shaarli</strong><br />
Télécharger la dernière version de Shaarli depuis la <a href="https://github.com/shaarli/Shaarli/releases">page des versions</a> (Télécharger larchive <strong>shaarli-full</strong> pour inclure les dépendances).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://github.com/shaarli/Shaarli/releases/download/v0.11.1/shaarli-v0.11.1-full.tar.gz
unzip shaarli-v0.11.1-full.tar.gz
sudo mv Shaarli /var/www/shaarli
sudo chown shaarli:shaarli -R /var/www/shaarli
</code></pre></div></div>
<p>Ouvrir le lien https://shaarli.cinay.xyz pour le paramétrage</p>
<p><img src="/images/shaarli01.png" alt="" width="500" /> <br />
Après linstallation, se connecter en utilisateur/mot de passe</p>
<p><img src="/images/shaarli-web.png" alt="" width="400px" /><br />
<a href="https://shaarli.cinay.xyz/">https://shaarli.cinay.xyz/</a></p>
<h3 id="wallabag-publique-lienscinayxyz">Wallabag (publique liens.cinay.xyz)</h3>
<p><em>wallabag est une application libre à héberger sur serveur permettant de sauvegarder des articles puis de les lire plus tard, sur nimporte quel appareil (navigateur, smartphone, tablette ou liseuse), que vous soyez connecté ou non.</em></p>
<p>Création domaine liens.cinay.xyz et certificats SSL<br />
Installation de lapplication “Wallabag for YunoHost” sur le domaine <strong>liens.cinay.xyz</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/wallabag2_ynh.git
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WARNING! Installing 3rd party applications may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. Are you willing to take that risk? [Y/N] : Y
Available domains:
- cinay.xyz
- map.cinay.xyz
- blog.cinay.xyz
- gitea.cinay.xyz
- liens.cinay.xyz
- static.cinay.xyz
- calibre.cinay.xyz
- shaarli.cinay.xyz
Choose a domain for Wallabag (default: cinay.xyz): liens.cinay.xyz
Choose a path for Wallabag (default: /wallabag): /
Available users:
- yannick
Choose the Wallabag administrator: yannick
Info: Installing application wallabag2…
Info: [....................] &gt; Validating installation parameters...
Info: [++++................] &gt; Installing dependencies...
Info: [####................] &gt; Creating a MySQL database...
Info: [####++..............] &gt; Setting up source files...
Info: [######+.............] &gt; Configuring nginx web server...
Info: [#######.............] &gt; Configuring system user...
Info: [#######+............] &gt; Configuring php-fpm...
Info: [########+++++++++++.] &gt; Configuring wallabag...
Info: [###################.] &gt; Configuring SSOwat...
Info: [###################.] &gt; Reloading nginx web server...
Info: [####################] &gt; Installation of wallabag2 completed
Success! The SSOwat configuration has been generated
Success! Installation complete
</code></pre></div></div>
<h3 id="monitorix---privée-moncinayxyz">Monitorix - (privée mon.cinay.xyz)</h3>
<p><em>Monitorix est un outil de surveillance de système gratuit, open source et léger, conçu pour surveiller le plus grand nombre possible de services et de ressources du système. Il a été créé pour être utilisé sous des serveurs Linux/UNIX de production, mais en raison de sa simplicité et de sa petite taille, il peut également être utilisé sur des appareils embarqués.</em></p>
<p>Installer domaine et certificats</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add mon.cinay.xyz
yunohost domain cert-install mon.cinay.xyz
</code></pre></div></div>
<p>Installer une application</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/monitorix_ynh
</code></pre></div></div>
<h2 id="sites-statiques-jekyll">Sites statiques (jekyll)</h2>
<h3 id="publique-staticcinayxyz">Publique static.cinay.xyz</h3>
<p><img src="/images/jekyll-300x133.png" alt="image" width="150px" /></p>
<p><strong>Création domaine static.cinay.xyz</strong><br />
En mode administrateur ou en ligne de commande, créer un domaine static.cinay.xyz puis générer les certificats letsencrypt</p>
<p>En ligne de commande (passer en root)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add static.cinay.xyz
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Administration password:
Success! Successfully installed a self-signed certificate for domain static.cinay.xyz!
Success! The configuration has been updated for service 'postfix'
Success! The configuration has been updated for service 'nginx'
Success! The configuration has been updated for service 'dnsmasq'
Success! The configuration has been updated for service 'metronome'
Success! The SSOwat configuration has been generated
Success! The domain has been created
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain cert-install static.cinay.xyz
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Info: Now attempting install of certificate for domain static.cinay.xyz!
Success! The SSOwat configuration has been generated
Success! The configuration has been updated for service 'dnsmasq'
Info: Parsing account key...
Info: Parsing CSR...
Info: Registering account...
Info: Already registered!
Info: Verifying static.cinay.xyz...
Info: static.cinay.xyz verified!
Info: Signing certificate...
Info: Certificate signed!
Success! Successfully installed Let's Encrypt certificate for domain static.cinay.xyz!
</code></pre></div></div>
<h3 id="rbenv-gestion-des-versions-ruby">rbenv gestion des versions ruby</h3>
<p>Rbenv est un outil léger de gestion des versions de Ruby qui vous permet de changer facilement de version de Ruby.</p>
<p>Par défaut, Rbenv ne gère pas linstallation des versions de Ruby. ruby-build est un outil qui vous aide à installer nimporte quelle version de Ruby dont vous pourriez avoir besoin. Il est disponible en tant que programme autonome et en tant que plugin pour rbenv.</p>
<p>Installez les dépendances nécessaires à loutil ruby-build pour construire Ruby à partir des sources :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt update
sudo apt install git curl libssl-dev libreadline-dev zlib1g-dev autoconf bison build-essential libyaml-dev libreadline-dev libncurses5-dev libffi-dev libgdbm-dev
</code></pre></div></div>
<p>Ensuite, lancez la commande curl suivante pour installer les scripts rbenv et ruby-build :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -sL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer | bash -
</code></pre></div></div>
<p>Si linstallation est réussie, le script imprimera quelque chose comme ceci :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Running doctor script to verify installation...
Checking for `rbenv' in PATH: not found
You seem to have rbenv installed in `/home/dbsuser/.rbenv/bin', but that
directory is not present in PATH. Please add it to PATH by configuring
your `~/.bashrc', `~/.zshrc', or `~/.config/fish/config.fish'.
</code></pre></div></div>
<p>Avant de commencer à utiliser rbenv, nous devons ajouter $HOME/.rbenv/bin à notre PATH.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo 'export PATH="$HOME/.rbenv/bin:$PATH"' &gt;&gt; ~/.bashrc
echo 'eval "$(rbenv init -)"' &gt;&gt; ~/.bashrc
source ~/.bashrc
</code></pre></div></div>
<p>Les dernières versions stables</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rbenv install -l
</code></pre></div></div>
<p>Maintenant que rbenv est installé sur notre système, nous pouvons facilement installer la dernière version stable de Ruby et la définir comme version par défaut avec :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rbenv install 2.7.1
rbenv global 2.7.1
</code></pre></div></div>
<p>Vérifiez que Ruby a été correctement installé en imprimant le numéro de version :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ruby -v
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]</code></p>
<h3 id="installer-jekyll-via-gem-et-bundler">Installer jekyll via gem et bundler</h3>
<p>On va utiliser gem pour installer Jekyll et Bundler qui est un outil utilisé pour gérer les dépendances de Gem.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>which bundler
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">/home/debadm/.rbenv/shims/bundler</code></p>
<p>Installer jekyl</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem install jekyll # Patienter quelques minutes
jekyll -v
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">jekyll 4.1.1</code></p>
<p>Cloner le dépôt staticyan</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://gitea.cinay.eu/yann/staticyan.git
sudo mv staticyan /srv/
sudo chown $USER.$USER -R /srv/staticyan
cd /srv/staticyan/
</code></pre></div></div>
<p>Vérifier Gemfile</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source 'https://rubygems.org'
gem "jekyll", github: "jekyll/jekyll"
group :jekyll_plugins do
gem "pygments.rb"
gem "jekyll-paginate"
gem 'jekyll-toc'
gem 'jekyll-last-modified-at'
gem 'rouge'
end
</code></pre></div></div>
<p>Installer jekyll via bundle</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle install
</code></pre></div></div>
<p>Les dossiers <em>images</em> <em>files</em> et <em>_posts</em> du site statique sont synchronisés par nextcloud dans /home/yannick/statique , il faut créer des liens avec jekyll</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree -L 1 /home/yannick/statique/
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/home/yannick/statique/
├── files
├── images
└── _posts
</code></pre></div></div>
<p>Création des liens</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm -rf /srv/staticyan/{files,images,_posts} # suppression des dossiers existants
sudo ln -s /home/yannick/statique/_posts /srv/staticyan/_posts
sudo ln -s /home/yannick/statique/images /srv/staticyan/images
sudo ln -s /home/yannick/statique/files /srv/staticyan/files
</code></pre></div></div>
<p>Ce qui donne</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree -L 1 /srv/staticyan/
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/srv/staticyan/
├── 404.html
├── assets
├── categories.html
├── _config.yml
├── feed.xml
├── files -&gt; /home/yannick/statique/files
├── Gemfile
├── Gemfile.lock
├── images -&gt; /home/yannick/statique/images
├── _includes
├── index.html
├── _layouts
├── _posts -&gt; /home/yannick/statique/_posts
├── README.md
├── _site
├── start.sh
├── tags.html
└── wikistatic.json
</code></pre></div></div>
<p><strong>Créer service staticyan</strong></p>
<p>Pour lancer le serveur <strong>staticyan</strong> au démarrage, utilisation dun <u>service systemd</u><br />
<strong>ATTENTION!</strong> , remplacer <em>User=utilisateur</em> par votre nom dutilisateur <code class="language-plaintext highlighter-rouge">echo $USER</code><br />
Relever le chemin complet de bundle : <code class="language-plaintext highlighter-rouge">which bundle</code></p>
<p>Création dun service “staticyan” sous systemd</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/systemd/system/staticyan.service
</code></pre></div></div>
<p>Contenu du fichier</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Unit]</span>
<span class="py">Description</span><span class="p">=</span><span class="s">service staticyan</span>
<span class="py">After</span><span class="p">=</span><span class="s">network.target</span>
<span class="nn">[Service]</span>
<span class="py">Type</span><span class="p">=</span><span class="s">simple</span>
<span class="py">User</span><span class="p">=</span><span class="s">debadm</span>
<span class="py">WorkingDirectory</span><span class="p">=</span><span class="s">/srv/staticyan</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/home/debadm/.rbenv/shims/bundle exec jekyll build --watch</span>
<span class="py">Restart</span><span class="p">=</span><span class="s">on-abort</span>
<span class="nn">[Install]</span>
<span class="py">WantedBy</span><span class="p">=</span><span class="s">multi-user.target</span>
</code></pre></div></div>
<p>Lancer le service <strong>staticyan</strong> :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl daemon-reload
sudo systemctl start staticyan
#Vérifier
sudo systemctl status staticyan
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>● staticyan.service - jekyll Service
Loaded: loaded (/etc/systemd/system/staticyan.service; disabled; vendor preset: enabled)
Active: active (running) since Sun 2020-07-05 15:42:16 CEST; 16s ago
Main PID: 31137 (bundle)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/staticyan.service
└─31137 /home/debadm/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bin/jekyll build --watch
Jul 05 15:42:16 cinay.xyz systemd[1]: Started jekyll Service.
Jul 05 15:42:18 cinay.xyz bundle[31137]: Configuration file: /srv/staticyan/_config.yml
Jul 05 15:42:18 cinay.xyz bundle[31137]: Source: /srv/staticyan
Jul 05 15:42:18 cinay.xyz bundle[31137]: Destination: /srv/staticyan/_site
Jul 05 15:42:18 cinay.xyz bundle[31137]: Incremental build: disabled. Enable with --incremental
Jul 05 15:42:18 cinay.xyz bundle[31137]: Generating...
</code></pre></div></div>
<p>Valider le lancement du service staticyan au démarrage</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable staticyan
</code></pre></div></div>
<blockquote>
<p>jekyll génére un dossier statique <strong>/srv/staticyan/_site</strong></p>
</blockquote>
<p>Installation de lapplication “Multi webapp for YunoHost” sur le domaine <strong>static.cinay.xyz</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/multi_webapp_ynh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WARNING! Installing 3rd party applications may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. Are you willing to take that risk? [Y/N] : Y
Available domains:
- cinay.xyz
- map.cinay.xyz
- blog.cinay.xyz
- liens.cinay.xyz
- static.cinay.xyz
Choose a domain for your Webapp (default: cinay.xyz): static.cinay.xyz
Choose a path for your Webapp (default: /site): /
Available users:
- yannick
Choose the YunoHost user: yannick
Create a database? [yes | no] (default: no):
Is it a public website ? [yes | no] (default: no): yes
Info: [....................] &gt; Retrieve arguments from the manifest
Info: [#...................] &gt; Check if the app can be installed
Info: [##..................] &gt; Store settings from manifest
Info: [#####...............] &gt; Setup SSOwat
Info: [######..............] &gt; Create final path
Info: The directory /var/www/webapp_yannick already exist, do not recreate it.
Info: [#######.............] &gt; Create a dedicated user
Warning: Reload the service php7.0-fpm
Info: [##########..........] &gt; Configure php-fpm
Info: [###########.........] &gt; Configure nginx
Warning: Reload the service nginx
Info: [############........] &gt; Reload nginx
Info: [####################] &gt; Installation completed
Success! The SSOwat configuration has been generated
Success! Installation complete
</code></pre></div></div>
<p>Le dossier par défaut de “Multi webapp for YunoHost” <strong>/var/www/webapp_yannick/static.cinay.xyz_/</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm -r /var/www/webapp_yannick/static.cinay.xyz_/ # on supprime le dossier par défaut
sudo ln -s /srv/staticyan/_site /var/www/webapp_yannick/static.cinay.xyz_ # créer le lien
</code></pre></div></div>
<blockquote>
<p>Changer létiquette par “Static” en utilisant ladministration web “Applications”</p>
</blockquote>
<p><img src="/images/static-web.png" alt="static-web" width="400px" /><br />
Le site statique sur le lien <a href="https://static.xoyize.xyz">https://static.xoyize.xyz</a></p>
<h4 id="menu-sur-les-posts-jekyll-toc">Menu sur les “posts” (jekyll-toc)</h4>
<p>Installer jekyll-toc : <code class="language-plaintext highlighter-rouge">gem install jekyll-toc</code> <br />
Ajouter <code class="language-plaintext highlighter-rouge">jekyll-toc</code> à la rubrique <em>plugins</em> du fichier <strong>_config.yml</strong><br />
Modifier le fichier _includes/posts.html : <code class="language-plaintext highlighter-rouge">content</code><code class="language-plaintext highlighter-rouge">content | toc </code></p>
<p>Le temps de génération du site est multiplié par 6 (on passe de 5 à 30 secondes ???)<br />
La solution est de passer en mode incrémental (seul le fichier modifié est regénéré)</p>
<p>Modifier le service <code class="language-plaintext highlighter-rouge">sudo nano /etc/systemd/system/staticyan.service</code> : <br />
Remplacer <code class="language-plaintext highlighter-rouge">ExecStart=/home/debadm/.rbenv/shims/bundle exec jekyll build --watch</code> <br />
Par <code class="language-plaintext highlighter-rouge">ExecStart=/home/debadm/.rbenv/shims/bundle exec jekyll build --watch --incremental</code><br />
Recharger <code class="language-plaintext highlighter-rouge">sudo systemctl daemon-reload</code> et relancer <code class="language-plaintext highlighter-rouge">sudo systemctl start staticyan</code></p>
<h3 id="privée-blogcinayxyz-facultatif">Privée blog.cinay.xyz (FACULTATIF)</h3>
<p>Essais → <a href="https://blog.cinay.xyz/2019/12/Blog-statique-jekyll-Yunohost-cinay.xyz.html">Blog statique de type jekyll sur site cinay.xyz</a></p>
<blockquote>
<p>Site statique de type jekyll identique dans la conception à static.cinay.xyz</p>
</blockquote>
<p>Yunohost administrateur</p>
<ol>
<li>Ajout domaine <strong>blog.cinay.xz</strong></li>
<li>Certificats Lets Encrypt pour le domaine</li>
<li>Installer lapplication <strong>Multi webapp for YunoHost</strong>
<ul>
<li>domaine : blog.cinay.xyz</li>
<li>Chemin : /</li>
<li>Site publique : Non</li>
</ul>
</li>
</ol>
<p><img src="/images/blog-web.png" alt="" width="400px" /><br />
Accès site blog/test <a href="https://blog.cinay.xyz">https://blog.cinay.xyz</a></p>
<p>Le dossier par défaut de “Multi webapp for YunoHost” <strong>/var/www/webapp_yannick/blog.cinay.xyz_/</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm -r /var/www/webapp_yannick/blog.cinay.xyz_/ # on supprime le dossier par défaut
sudo ln -s /srv/basicblog/_site /var/www/webapp_yannick/blog.cinay.xyz_ # créer le lien
</code></pre></div></div>
<blockquote>
<p>MODIFICATION , ajout exclusion dossier <strong>_posts/archives</strong> dans le fichier de configuration <strong>_config.yml</strong></p>
</blockquote>
<p><strong>Modifications sur static et blog</strong></p>
<p>Le but recherché est un accès publique sur le site static.cinay.xyz et privé sur le site blog.cinay.xyz.</p>
<ul>
<li><strong>static.cinay.xyz</strong> accède au dossier pour les billets <strong>publiques</strong></li>
<li><strong>blog.cinay.xyz</strong> accède au dossier pour les billets <strong>publiques et privés</strong></li>
</ul>
<p>Arrêt des services</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl stop jekyll
sudo systemctl stop basicblog
</code></pre></div></div>
<p><strong>static.cinay.xyz</strong></p>
<p>Exclusions dans <strong>static.cinay.xyz</strong> (fichier de configuration <strong>/srv/wikistatic/_config.yml</strong>)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>exclude:
- .jekyll-cache
- _posts/archives/
- _posts/private/
</code></pre></div></div>
<p>Les liens</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ls -l /srv/wikistatic/ |grep ^l
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>lrwxrwxrwx 1 debadm debadm 28 Apr 12 10:25 files -&gt; /home/yannick/statique/files
lrwxrwxrwx 1 debadm debadm 29 Apr 12 10:26 images -&gt; /home/yannick/statique/images
lrwxrwxrwx 1 debadm debadm 29 Apr 12 10:27 _posts -&gt; /home/yannick/statique/_posts
</code></pre></div></div>
<p><strong>blog.cinay.xyz</strong></p>
<p>Exclusions dans <strong>blog.cinay.xyz</strong> (fichier de configuration <strong>/srv/basicblog/_config.yml</strong>)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>exclude:
- .jekyll-cache
- _posts/archives/
</code></pre></div></div>
<p>Modifier le lien _posts</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ls -l /srv/basicblog/ |grep ^l
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>lrwxrwxrwx 1 debadm debadm 28 Dec 25 12:18 files -&gt; /home/yannick/statique/files
lrwxrwxrwx 1 debadm debadm 29 Dec 25 12:18 images -&gt; /home/yannick/statique/images
lrwxrwxrwx 1 debadm debadm 37 Apr 12 10:22 _posts -&gt; /home/yannick/statique/_posts
</code></pre></div></div>
<p><strong>basicblog</strong><br />
Ajout affichage de la lettre P sur fond rouge , si le billet contient le tag <code class="language-plaintext highlighter-rouge">private: true</code></p>
<p><strong>Redémarrer les services</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start jekyll
sudo systemctl start basicblog
</code></pre></div></div>
<h2 id="sauvegarde-yunohost">Sauvegarde yunohost</h2>
<p>Création dune sauvegarde complète yunohost</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
yunohost backup create -n Backup-Yunohost-cinay.xyz
</code></pre></div></div>
<p>Sauvegarde automatique tous les jours</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
crontab -e
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Sauvegarde yunohost
15 01 * * * /bin/rm /home/yunohost.backup/archives/* &amp;&amp; /usr/bin/yunohost backup create -n Backup-Yunohost-cinay.xyz &gt; /dev/null
</code></pre></div></div>
<h2 id="sauvegarde-borgbackup">Sauvegarde BorgBackup</h2>
<p><img src="/images/borg-logo.png" alt="" /></p>
<h3 id="serveur-client-cinayxyz">serveur client cinay.xyz</h3>
<h4 id="connexion-ssh">connexion SSH</h4>
<blockquote>
<p>Pour une connexion via ssh vous devez ajouter la clé publique <em>cinay_ed25519</em> du <strong>serveur client cinay.xyz</strong> au fichier <em>~/.ssh/authorized_keys</em> du <strong>serveur backup xoyaz.xyz</strong></p>
</blockquote>
<p>Procédure</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh usernl@5.2.79.107 -p 55036 -i /home/yannick/.ssh/OVZ-STORAGE-128 # connexion SSH serveur backup
sudo -s # passer en super utilisateur
cat &gt;&gt; /srv/data/borg-backups/.ssh/authorized_keys
</code></pre></div></div>
<p>Copier/coller le contenu du fichier du fichier de clef publique (fichier /root/.ssh/cinay_ed25519.pub de la machine à sauvegarder <strong>cinay.xyz</strong> ) dans ce terminal, et presser [Ctrl]+[D] pour valider.</p>
<p>Test depuis le serveur client (cest lui qui possède la clé privée)</p>
<blockquote>
<p><strong>AU PREMIER passage une question est posée , saisir oui ou yes</strong></p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
ssh -p 55036 -i /root/.ssh/cinay_ed25519 borg@xoyaz.xyz
The authenticity of host '[xoyaz.xyz]:55036 ([2a04:52c0:101:7ae::7a5e]:55036)' can't be established.
ECDSA key fingerprint is SHA256:PDXQBhTh4oj0cSzgnjCun+J60JDUEk7VeLH2YHZbwMc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[xoyaz.xyz]:55036,[2a04:52c0:101:7ae::7a5e]:55036' (ECDSA) to the list of known hosts.
Linux backup 2.6.32-042stab134.3 #1 SMP Sun Oct 14 12:26:01 MSK 2018 x86_64
_ _
| |__ __ _ __ | |__ _ _ _ __
| '_ \/ _` |/ _|| / /| || || '_ \
|_.__/\__,_|\__||_\_\ \_,_|| .__/
|_|
$ pwd
/srv/data/borg-backups
$
# saisir exit pour sortir
</code></pre></div></div>
<h4 id="création-du-dépôt-distant-cinayxyz-a-faire-une-seule-fois">Création du dépôt distant cinay.xyz (A FAIRE UNE SEULE FOIS)</h4>
<p>Dans la terminologie borg, lemplacement où les sauvegardes sont stockées est appelé le référentiel borg (dépôt).</p>
<p>sudo -s</p>
<p>Créer un fichier avec la passphrase <code class="language-plaintext highlighter-rouge">nano /root/.borg/passphrase</code> et copier le résultat de la commande <code class="language-plaintext highlighter-rouge">&lt; /dev/urandom tr -dc A-Za-z0-9 | head -c${1:-64};echo;</code> dans le fichier</p>
<p>Initialisation dépôt</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export BORG_PASSPHRASE="`cat /root/.borg/passphrase`"
export BORG_RSH='ssh -i /root/.ssh/cinay_ed25519'
borg init --encryption=repokey-blake2 ssh://borg@xoyaz.xyz:55036/srv/data/borg-backups/cinay.xyz
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Remote: Borg 1.0.9: exception <span class="k">in </span>RPC call:
Remote: Traceback <span class="o">(</span>most recent call last<span class="o">)</span>:
Remote: File <span class="s2">"/usr/lib/python3/dist-packages/borg/remote.py"</span>, line 108, <span class="k">in </span>serve
Remote: raise InvalidRPCMethod<span class="o">(</span>method<span class="o">)</span>
Remote: borg.remote.InvalidRPCMethod: get_free_nonce
Remote: Platform: Linux backup 2.6.32-042stab134.3 <span class="c">#1 SMP Sun Oct 14 12:26:01 MSK 2018 x86_64</span>
Remote: Linux: debian 9.9
Remote: Borg: 1.0.9 Python: CPython 3.5.3
Remote: PID: 18282 CWD: /srv/data/borg-backups
Remote: sys.argv: <span class="o">[</span><span class="s1">'/usr/bin/borg'</span>, <span class="s1">'serve'</span>, <span class="s1">'--umask=077'</span><span class="o">]</span>
Remote: SSH_ORIGINAL_COMMAND: None
Remote:
Please upgrade to borg version 1.1+ on the server <span class="k">for </span>safer AES-CTR nonce handling.
By default repositories initialized with this version will produce security
errors <span class="k">if </span>written to with an older version <span class="o">(</span>up to and including Borg 1.0.8<span class="o">)</span><span class="nb">.</span>
If you want to use these older versions, you can disable the check by running:
borg upgrade <span class="nt">--disable-tam</span> ssh://borg@xoyaz.xyz:55036/srv/data/borg-backups/cinay.xyz
See https://borgbackup.readthedocs.io/en/stable/changes.html#pre-1-0-9-manifest-spoofing-vulnerability <span class="k">for </span>details about the security implications.
IMPORTANT: you will need both KEY AND PASSPHRASE to access this repo!
Use <span class="s2">"borg key export"</span> to <span class="nb">export </span>the key, optionally <span class="k">in </span>printable format.
Write down the passphrase. Store both at safe place<span class="o">(</span>s<span class="o">)</span><span class="nb">.</span>
</code></pre></div></div>
<h4 id="sauvegarde-cinayxyz--xoyazxyz">Sauvegarde cinay.xyz → xoyaz.xyz</h4>
<p>Le fichier des exclusions</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /root/.borg/exclusions
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/dev
/proc
/sys
/tmp
/run
/mnt
/media
lost+found
/home/yunohost.*
/opt
</code></pre></div></div>
<p>Créer un bash</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
nano /root/.borg/borg-backup
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/sh
#
# Script de sauvegarde.
#
# Envoie les sauvegardes sur un serveur distant, via le programme Borg.
# Les sauvegardes sont chiffrées
#
set -e
BACKUP_DATE=`date +%Y-%m-%d-%Hh%M`
LOG_PATH=/var/log/borg-backup.log
export BORG_PASSPHRASE="`cat ~root/.borg/passphrase`"
export BORG_RSH='ssh -i /root/.ssh/cinay_ed25519'
BORG_REPOSITORY=ssh://borg@xoyaz.xyz:55036/srv/data/borg-backups/cinay.xyz
BORG_ARCHIVE=${BORG_REPOSITORY}::${BACKUP_DATE}
borg create \
-v --progress --stats --compression lzma,9 \
--exclude-caches \
$BORG_ARCHIVE \
/home/yunohost.backup \
&gt;&gt; ${LOG_PATH} 2&gt;&amp;1
# Nettoyage des anciens backups
# On conserve
# - une archive par jour les 7 derniers jours,
# - une archive par semaine pour les 4 dernières semaines,
# - une archive par mois pour les 6 derniers mois.
borg prune \
-v --list --stats --keep-daily=7 --keep-weekly=4 --keep-monthly=6 \
$BORG_REPOSITORY \
&gt;&gt; ${LOG_PATH} 2&gt;&amp;1
exit
# ancienne sauvegarde
borg create \
-v --stats --compression lzma,9 \
--exclude-from /root/.borg/exclusions.xoyaz.xyz --exclude-caches \
$BORG_ARCHIVE \
/ \
&gt;&gt; ${LOG_PATH} 2&gt;&amp;1
</code></pre></div></div>
<p>Le rendre exécutable</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x /root/.borg/borg-backup-xoyaz
</code></pre></div></div>
<p>On ajoute la sauvegarde des bases mariaDB sous forme SQL</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /root/.borg/dumpmysql.sh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/bash
# Configuration de base: datestamp e.g. YYYYMMDD
DATE=$(date +"%Y%m%d")
# Dossier où sauvegarder les backups (créez le d'abord!)
BACKUP_DIR="/srv/backup/mysql"
# Identifiants MySQL
MYSQL_USER="root"
MYSQL_PASSWORD=$(cat /etc/yunohost/mysql )
GZIP="$(which gzip)"
# Commandes MySQL (aucune raison de modifier ceci)
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
# Bases de données MySQL à ignorer
SKIPDATABASES="Database|information_schema|performance_schema|mysql"
# Nombre de jours à garder les dossiers (seront effacés après X jours)
RETENTION=14
# ---- NE RIEN MODIFIER SOUS CETTE LIGNE ------------------------------------------
#
# Create a new directory into backup directory location for this date
mkdir -p $BACKUP_DIR/$DATE
# Retrieve a list of all databases
databases=`$MYSQL -u$MYSQL_USER -p$MYSQL_PASSWORD -e "SHOW DATABASES;" | grep -Ev "($SKIPDATABASES)"`
# Dump the databases in seperate names and gzip the .sql file
for db in $databases; do
echo $db
$MYSQLDUMP --force --opt --user=$MYSQL_USER -p$MYSQL_PASSWORD --skip-lock-tables --events --databases $db | $GZIP &gt; "$BACKUP_DIR/$DATE/$db.sql.gz"
done
# Remove files older than X days
find $BACKUP_DIR/* -mtime +$RETENTION -delete
</code></pre></div></div>
<p>Le rendre exécutable</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x /root/.borg/dumpmysql.sh
</code></pre></div></div>
<p>Programmer les tâches</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab -e # ajouter les ligne suivantes en fin de fichier
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Sauvegarde sur serveur de backup distant xoyaz.xyz avec BorgBackup
30 01 * * * /root/.borg/dumpmysql.sh &gt; /dev/null
00 02 * * * /root/.borg/borg-backup-xoyaz &gt; /dev/null
</code></pre></div></div>
<h2 id="ajout-dune-clé-diffie-hellman-et-vérification-par-ssllabs">Ajout dune clé Diffie-Hellman et vérification par SSLlabs</h2>
<h3 id="ajout-dune-clé-diffie-hellman">Ajout dune clé Diffie-Hellman</h3>
<p><em>Lalgorithme Diffie-Hellman est un algorithme déchange de clés, utilisé notamment lors de louverture dune connexion à un site sécurisé via le protocole SSL/TLS.</em></p>
<p>Exécuter les instructions suivantes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># passer en mode su
sudo -s
# Générer une clé Diffie Hellman (patienter quelques minutes)
openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048
# Enlever commentaire en début de ligne sur tous les fichiers de configuration nginx
find /etc/nginx/conf.d/ -name "*.conf" -exec sed -i 's/#ssl_dhparam/ssl_dhparam/g' {} \;
# Redémarrer nginx
systemctl restart nginx
# sortie su
exit
</code></pre></div></div>
<h3 id="vérification-par-ssllabs">Vérification par ssllabs</h3>
<p>Ouvrir le lien <a href="https://www.ssllabs.com/ssltest/analyze.html?d=cinay.xyz">https://www.ssllabs.com/ssltest/analyze.html?d=cinay.xyz</a> sur un navigateur et patienter…</p>
<p><img src="/images/ssllabs-cinay.xyz.png" alt="ssllabs" width="600" /></p>
<h2 id="go-node">Go Node</h2>
<h3 id="go">Go</h3>
<p><img src="/images/golang-color-icon2.png" alt="golang" width="50" /></p>
<p>Go installation (Debian) , installer la dernière version de Go (https://golang.org/dl/)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~
wget https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.14.2.linux-amd64.tar.gz
rm go1.14.2.linux-amd64.tar.gz
</code></pre></div></div>
<p>Environnement de configuration</p>
<p>Bash: <strong>~/.bashrc</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p $HOME/go
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" &gt;&gt; ~/.bashrc
echo "export GOPATH=$HOME/go" &gt;&gt; ~/.bashrc
source ~/.bashrc
</code></pre></div></div>
<h3 id="nodejs">Nodejs</h3>
<p><img src="/images/Node_logo.png" alt="nodejs" width="50" /></p>
<p>Installer la version LTS de nodejs pour le frontend.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install curl software-properties-common -y
curl -sL https://deb.nodesource.com/setup_12.x | sudo bash -
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>## Run `sudo apt-get install -y nodejs` to install Node.js 12.x and npm
## You may also need development tools to build native addons:
sudo apt-get install gcc g++ make
## To install the Yarn package manager, run:
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update &amp;&amp; sudo apt-get install yarn
</code></pre></div></div>
<p>Nodejs</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install -y nodejs
</code></pre></div></div>
<h2 id="serveur-audio-gonic-ziccinayxyz">Serveur Audio Gonic (zic.cinay.xyz)</h2>
<p><img src="/images/gonic002.png" alt="Texte alternatif" width="200" /><br />
<em><a href="https://github.com/sentriz/gonic">Gonic</a> écrit en go est une alternative à Subsonic.org, accessible par un proxy nginx<br />
La seule application qui accepte de fonctionner avec répertoires montés par FUSE.</em></p>
<h3 id="caractéristiques">Caractéristiques</h3>
<ul>
<li>la navigation par dossier (en gardant votre arborescence complète intacte)</li>
<li>la navigation par balises (à laide de <a href="https://taglib.org/">taglib</a> - supporte mp3, opus, flac, ape, m4a, wav, etc.)</li>
<li>transcodage et mise en cache audio à la volée (nécessite <a href="https://ffmpeg.org/">ffmpeg</a>) (merci spijet)</li>
<li>balayage assez rapide (avec ma bibliothèque de ~27k pistes, le balayage initial prend environ 10m, et environ 5s après de manière incrémentielle)</li>
<li>plusieurs utilisateurs, chacun ayant ses propres préférences de transcodage, ses listes de lecture, ses meilleures pistes, ses meilleurs artistes, etc.</li>
<li><a href="https://www.last.fm/">last.fm</a> scrobbling</li>
<li>similarités entre les artistes et biographies de la dernière api.fm</li>
<li>une interface web pour la configuration (configurer last.fm, gérer les utilisateurs, lancer des analyses, etc.)</li>
<li>un support pour le tag album-artist, pour ne pas encombrer votre liste dartistes avec des apparitions dalbums de compilation</li>
<li>écrit en go, donc léger et adapté à un pi framboise, etc.</li>
<li>plus récent sel et token auth</li>
<li>testé sur <a href="https://f-droid.org/en/packages/github.daneren2005.dsub/">dsub</a>, <a href="http://jamstash.com/">jamstash</a>, <a href="https://gitlab.com/sumner/sublime-music/">musique sublime</a> et<a href="https://apps.apple.com/us/app/soundwaves/id736139596"> ondes sonores</a></li>
</ul>
<h3 id="sshfs-fstab">SSHFS fstab</h3>
<p>Le dossier “musique” est distant (serveur xoyaz.xyz)<br />
Il faut créer une liaison réseau sécurisée entre <strong>cinay.xyz ← → xoyaz.xyz</strong><br />
On va utiliser SSHFS (<em>Secure shell file system (ou SSHFS) permet le partage dun système de fichiers de manière sécurisée en utilisant le protocole SFTP de SSH</em>)</p>
<p>Créer un dossier “backup” local</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkdir -p /opt/backup
</code></pre></div></div>
<p>Installation</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install sshfs
</code></pre></div></div>
<p>Autorisations</p>
<ul>
<li>Autorisations “utilisateur”
<ul>
<li>Exécuter <code class="language-plaintext highlighter-rouge">sshfs</code> (ou toute autre commande de montage FUSE) avec loption <code class="language-plaintext highlighter-rouge">-o allow_other</code></li>
</ul>
</li>
<li>Autoriser laccès “root” des supports <strong>fuse</strong>
<ul>
<li>Ajouter <code class="language-plaintext highlighter-rouge">user_allow_other</code> au fichier <strong>/etc/fuse.conf</strong></li>
<li>Exécuter <code class="language-plaintext highlighter-rouge">sshfs</code> (ou toute autre commande de montage FUSE) avec loption <code class="language-plaintext highlighter-rouge">-o allow_root</code></li>
</ul>
</li>
</ul>
<p>Clé privée <strong>OVZ-STORAGE-128</strong> pour accéder au serveur xoyaz.xyz</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod 600 //home/debadm/.ssh/OVZ-STORAGE-128
</code></pre></div></div>
<p><strong>Exécution manuelle</strong> pour authentifier la clé avec utilisateur “debian”</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
sshfs -o allow_other usernl@5.2.79.107:/home/usernl/backup /opt/backup -C -p 55036 -oIdentityFile=//home/debadm/.ssh/OVZ-STORAGE-128
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The authenticity of host '[5.2.79.107]:55036 ([5.2.79.107]:55036)' can't be established.
ECDSA key fingerprint is SHA256:PDXQBhTh4oj0cSzgnjCun+J60JDUEk7VeLH2YHZbwMc.
Are you sure you want to continue connecting (yes/no)? yes
</code></pre></div></div>
<blockquote>
<p>NOTE: Il est préférable de mettre ladresse IP du serveur ,les domaines peuvent ne pas être “résolus”</p>
</blockquote>
<p>Après vérification , <code class="language-plaintext highlighter-rouge">ls ~/music</code> , déconnexion <code class="language-plaintext highlighter-rouge">sudo fusermount -u /opt/gonic/music</code></p>
<p><strong>Montage fstab</strong></p>
<p>ajouter la ligne suivante au fichier <strong>/etc/fstab</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>usernl@5.2.79.107:/home/usernl/backup /opt/backup fuse.sshfs _netdev,identityfile=//home/debadm/.ssh/OVZ-STORAGE-128,allow_other,port=55036 0 0
</code></pre></div></div>
<p>Montage pour authentifier la clé avec utilisateur “root”</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mount -a
</code></pre></div></div>
<p>Vérification</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ls /opt/backup/musique/
</code></pre></div></div>
<blockquote>
<p><strong>ATTENTION!!! NE PAS OUBLIER DEXCLURE <code class="language-plaintext highlighter-rouge">/opt/backup</code> DE TOUTE SAUVEGARDE (/root/.borg/exclusions.xoyaz.xyz)</strong></p>
</blockquote>
<h3 id="installation-gonic">Installation gonic</h3>
<p>dans le répertoire utilisateur <strong>$HOME</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># les dépendances
sudo apt install build-essential git sqlite libtag1-dev ffmpeg libasound2-dev pkg-config # for debian like
cd $HOME/
# cloner
git clone https://gitea.cinay.eu/yann/golang-subsonic.git
cd golang-subsonic/
</code></pre></div></div>
<p>Construire lexécutable “gonic” et le copier dans /usr/local/bin</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./_do_build_server
sudo cp gonic /usr/local/bin/
</code></pre></div></div>
<h3 id="créer-le-service-gonic">Créer le service gonic</h3>
<p>Que fait le service ?</p>
<ul>
<li>Le dossier fuse “music” et monté au démarrage par fstab</li>
<li>lancer le serveur “gonic” en écoute local sur le port 4747 avec les options <code class="language-plaintext highlighter-rouge">-music-path</code>, <code class="language-plaintext highlighter-rouge">-db-path</code> et <code class="language-plaintext highlighter-rouge">-proxy-prefix</code></li>
<li>A larrêt,tuer la tâche “gonic”</li>
</ul>
<p>Tester le serveur</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/local/bin/gonic -music-path /opt/backup/musique -db-path /opt/gonic/gonic.db -proxy-prefix /
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2020/05/19 17:56:37 starting gonic v0.8.8
2020/05/19 17:56:37 provided config
2020/05/19 17:56:37 cache-path /tmp/gonic_cache
2020/05/19 17:56:37 config-path
2020/05/19 17:56:37 db-path /opt/gonic/gonic.db
2020/05/19 17:56:37 jukebox-enabled false
2020/05/19 17:56:37 listen-addr 0.0.0.0:4747
2020/05/19 17:56:37 music-path /opt/gonic/music
2020/05/19 17:56:37 proxy-prefix /
2020/05/19 17:56:37 scan-interval 0
2020/05/19 17:56:37 version false
2020/05/19 17:56:37 migration (1/7) '202002192100' finished
2020/05/19 17:56:37 migration (2/7) '202002192019' finished
2020/05/19 17:56:37 migration (3/7) '202002192222' finished
2020/05/19 17:56:37 migration (4/7) '202003111222' finished
2020/05/19 17:56:37 migration (5/7) '202003121330' finished
2020/05/19 17:56:37 migration (6/7) '202003241509' finished
2020/05/19 17:56:37 migration (7/7) '202004302006' finished
2020/05/19 17:56:37 starting job 'http'
</code></pre></div></div>
<p>Arrêt par Ctrl+C</p>
<p>Chaque service généré par systemd est configuré par un fichier .service qui se trouve dans le répertoire <strong>/etc/systemd/system</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/systemd/system/gonic.service
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
Description=Gonic audio server
After=network.target
[Service]
Type=simple
Restart=on-failure
RestartSec=10
ExecStart=/usr/local/bin/gonic -music-path /opt/backup/musique -db-path /opt/gonic/gonic.db -proxy-prefix /
[Install]
WantedBy=multi-user.target
</code></pre></div></div>
<p>Recharger <code class="language-plaintext highlighter-rouge">systemd</code> puis démarrer le service:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl daemon-reload
sudo systemctl start gonic.service
sudo systemctl status gonic.service
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>● gonic.service - Gonic audio server
Loaded: loaded (/etc/systemd/system/gonic.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-07-06 12:23:53 CEST; 13s ago
Main PID: 6431 (gonic)
Tasks: 6 (limit: 4915)
CGroup: /system.slice/gonic.service
└─6431 /usr/local/bin/gonic -music-path /opt/backup/musique -db-path /opt/gonic/gonic.db -proxy-prefix
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 cache-path /tmp/gonic_cache
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 config-path
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 db-path /opt/gonic/gonic.db
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 jukebox-enabled false
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 listen-addr 0.0.0.0:4747
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 music-path /opt/backup/musique
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 proxy-prefix /
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 scan-interval 0
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 version false
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 starting job 'http'
</code></pre></div></div>
<p>Visualiser le journal</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo journalctl -t gonic
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 starting gonic v0.8.8
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 provided config
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 cache-path /tmp/gonic_cache
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 config-path
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 db-path /opt/gonic/gonic.db
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 jukebox-enabled false
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 listen-addr 0.0.0.0:4747
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 music-path /opt/backup/musique
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 proxy-prefix /
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 scan-interval 0
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 version false
Jul 06 12:23:53 cinay.xyz gonic[6431]: 2020/07/06 12:23:53 starting job 'http'
</code></pre></div></div>
<p>Si tout est en ordre , on active le service</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable gonic.service
</code></pre></div></div>
<h3 id="ziccinayxyz">zic.cinay.xyz</h3>
<p>En mode su<br />
Créer le domaine zic.cinay.xyz : <code class="language-plaintext highlighter-rouge">yunohost domain add zic.cinay.xyz</code><br />
Les certificats : <code class="language-plaintext highlighter-rouge">yunohost domain cert-install zic.cinay.xyz</code></p>
<p>Installer lapplication Multi web app sur le domaine zic.cinay.xyz (accès publique)</p>
<h3 id="proxy-nginx">proxy nginx</h3>
<p><em>Gonic est un serveur local http sur le port 4747 et pour un accès externe il nous faut un proxy</em></p>
<p><strong>Proxy nginx</strong> - configuration <strong>/etc/nginx/conf.d/zic.cinay.xyz.d/webapp_zic.cinay.xyz_.conf</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#sub_path_only rewrite ^/$ / permanent;
location / {
# Proxy zic server
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:4747;
proxy_read_timeout 120;
# Include SSOWAT user panel.
include conf.d/yunohost_panel.conf.inc;
}
</code></pre></div></div>
<p>On vérifie et on relance le serveur nginx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nginx -t
</code></pre></div></div>
<p>En cas davertissement , modifier <strong>/etc/nginx/nginx.conf</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nginx -t
nginx: [warn] could not build optimal proxy_headers_hash, you should increase either proxy_headers_hash_max_size: 512 or proxy_headers_hash_bucket_size: 64; ignoring proxy_headers_hash_bucket_size
nginx: [warn] could not build optimal proxy_headers_hash, you should increase either proxy_headers_hash_max_size: 512 or proxy_headers_hash_bucket_size: 64; ignoring proxy_headers_hash_bucket_size
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
</code></pre></div></div>
<p>Ajouter au fichier <strong>/etc/nginx/nginx.conf</strong> , après <code class="language-plaintext highlighter-rouge">htpp {</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
</code></pre></div></div>
<p>Rechargement</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl reload nginx
</code></pre></div></div>
<p>Accès <a href="https://zic.cinay.xyz">https://zic.cinay.xyz</a></p>
<p><img src="/images/gonic003.png" alt="gonic" width="400" /></p>
<h2 id="diagramsnet">Diagrams.net</h2>
<p><em>Application en ligne qui permet de faire des schémas et du dessin vectoriel.</em></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/diagramsnet_ynh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Choose a domain name for Diagrams.net (default: cinay.xyz):
Choose a path for Diagrams.net (default: /diagram):
Is it a public application? [yes | no] (default: no):
</code></pre></div></div>
<h2 id="libreqr">LibreQR</h2>
<p><em>Un générateur de codes QR</em></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://code.antopie.org/miraty/qr_ynh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Choose a domain for LibreQR (default: cinay.xyz):
Choose a path for LibreQR (default: /qr):
Is it a public application? [yes | no] (default: yes):
</code></pre></div></div>
<h2 id="maintenance-yunohost">Maintenance yunohost</h2>
<h3 id="ajout-domaine-cinayeu-messagerie--obsolete">Ajout domaine cinay.eu (messagerie) -OBSOLETE</h3>
<p>Ajout domaine <strong>cinay.eu</strong> et utilisateur <strong>yann</strong><br />
Modification de la DNS OVH du domaine cinay.eu (<strong>NE CONCERNE QUE LA PARTIE MESSAGERIE</strong>)<br />
Les champs modifiés:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>IN MX 10 cinay.xyz.
IN TXT "v=spf1 a mx ip4:51.75.120.106 ip6:2001:41d0:305:2100::4dc0 -all"
IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTvvyg816px/VJY6XoyfyPpC8wtrziMU1IunI4AuMdP/WxnGr2HPR26ORn/n16PnNuyGdzC/AUG2917d2VJ88/oLQO8ZCePk4lcWFAqRyfPvyUc+nbnE8XhYbJ9udYzQ8zxsm/7LEfgFoOXKRi9DC7rgyf7F1sRUycS8MS6kIQxQIDAQAB"
IN TXT "v=DMARC1; p=none"
</code></pre></div></div>
<h3 id="nextcloud-1">Nextcloud</h3>
<p>Une mise à jour récente a déclenché un “upgrade” <strong>nextcloud</strong> de la version 15 à 18 <br />
Pour info la version 15 utilise php7.0 qui est installé par défaut<br />
La version 18 utilise PHP7.3</p>
<p>La mise à jour na pas posé de problème <br />
Par contre , des anomalies sont affichés lors de la consultation (en admin) des <em>avertissements de sécutité</em></p>
<p><strong>Anomalies</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Il est important pour la sécurité et la performance de votre instance que celle-ci soit correctement configurée. Afin de vous aider, votre instance Nextcloud effectue des vérifications automatiques. Pour de plus amples informations, veuillez consulter la documentation liée.
Il y a quelques avertissements concernant votre configuration.
MySQL est utilisée comme base de données mais ne supporte pas les caractères codés sur 4 octets. Pour pouvoir manipuler les caractères sur 4 octets (comme les émoticônes) sans problème dans les noms de fichiers ou les commentaires par exemple, il est recommandé d'activer le support 4 octets dans MySQL. Pour plus de détails, lisez la [page de documentation à ce sujet](https://docs.nextcloud.com/server/18/go.php?to=admin-mysql-utf8mb4)
La base de données a quelques index manquant. L'ajout d'index dans de grandes tables peut prendre un certain temps. Elles ne sont donc pas ajoutées automatiquement. En exécutant "occ db:add-missing-indices", ces index manquants pourront être ajoutés manuellement pendant que l'instance continue de tourner. Une fois les index ajoutés, les requêtes sur ces tables sont généralement beaucoup plus rapides.
Index "twofactor_providers_uid" manquant dans la table "oc_twofactor_providers".
Index "version" manquant dans la table "oc_whats_new".
Index "cards_abid" manquant dans la table "oc_cards".
Index "cards_prop_abid" manquant dans la table "oc_cards_properties".
Index "calendarobject_calid_index" manquant dans la table "oc_calendarobjects_props".
Index "schedulobj_principuri_index" manquant dans la table "oc_schedulingobjects".
Merci de consulter les [guides d'installation ↗](https://docs.nextcloud.com/server/18/go.php?to=admin-install) et de vérifier les erreurs ou avertissements des logs.
Vérifier la sécurité de votre Nextcloud grâce à notre [scan de sécurité ↗](https://scan.nextcloud.com/)
</code></pre></div></div>
<p><strong>Corrections MariaDb/nextcloud</strong></p>
<ul>
<li><a href="https://docs.nextcloud.com/server/18/go.php?to=admin-mysql-utf8mb4">Enabling MySQL 4-byte support</a></li>
</ul>
<p>Ouvrir 2 terminaux sur le site <br />
Respecter lordre des opérations</p>
<p><strong>→ PREMIER TERMINAL</strong></p>
<p>mysql -uroot -p$(cat /etc/yunohost/mysql )</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 76
Server version: 10.1.44-MariaDB-0+deb9u1 Debian 9.11
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]&gt; show variables like 'innodb_file_format';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| innodb_file_format | Antelope |
+--------------------+----------+
1 row in set (0.01 sec)
MariaDB [nextcloud]&gt; SET GLOBAL innodb_file_format=Barracuda;
Query OK, 0 rows affected (0.00 sec)
MariaDB [nextcloud]&gt; show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
1 row in set (0.00 sec)
MariaDB [(none)]&gt; quit
</code></pre></div></div>
<p><strong>→ SECOND TERMINAL</strong></p>
<p>ATTENTION /usr/bin/php7.3 est utilisé pour nextcloud</p>
<p>On passe en mode maintenance</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /var/www/nextcloud
sudo -u nextcloud /usr/bin/php7.3 occ maintenance:mode --on
</code></pre></div></div>
<p>Maintenance mode enabled</p>
<p>Redémarrer mysql suite aux manipulations effectuées dans le premier terminal</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart mysqld
</code></pre></div></div>
<p><strong>→ PREMIER TERMINAL</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql -uroot -p$(cat /etc/yunohost/mysql )
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MariaDB [(none)]&gt; ALTER DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]&gt; quit
</code></pre></div></div>
<p>Pour éviter lERREUR</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>An exception occurred while executing ALTER TABLE [TABLE_NAME] CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;:
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql -uroot -p$(cat /etc/yunohost/mysql ) nextcloud
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MariaDB [nextcloud]&gt; set global innodb_large_prefix=on;
Query OK, 0 rows affected (0.00 sec)
MariaDB [nextcloud]&gt; set global innodb_file_format=Barracuda;
Query OK, 0 rows affected (0.00 sec)
MariaDB [nextcloud]&gt; quit
Bye
</code></pre></div></div>
<p><strong>→ SECOND TERMINAL</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u nextcloud /usr/bin/php7.3 occ config:system:set mysql.utf8mb4 --type boolean --value="true"
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Nextcloud is in maintenance mode - no apps have been loaded
System config value mysql.utf8mb4 set to boolean true
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u nextcloud /usr/bin/php7.3 occ maintenance:repair # patienter
</code></pre></div></div>
<p>désactiver la maintenance</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u nextcloud /usr/bin/php7.3 occ maintenance:mode --off
</code></pre></div></div>
<p>Maintenance mode disabled</p>
<p><strong>Correction tâche cron</strong></p>
<p>La tâche cron nest jamais exécuté (normalement tous les 5 minutes) car elle nexiste pas</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Avertissements de sécurité &amp; configuration
Il est important pour la sécurité et la performance de votre instance que celle-ci soit correctement configurée. Afin de vous aider, votre instance Nextcloud effectue des vérifications automatiques. Pour de plus amples informations, veuillez consulter la documentation liée.
Il y a quelques erreurs concernant votre configuration.
Dernière tâche de fond a fonctionné il y a Il y a 1 heure. Quelque chose s'est mal passé. Vérifier les paramètres des tâches de fond
Merci de consulter les guides d'installation ↗ et de vérifier les erreurs ou avertissements des logs.
Vérifier la sécurité de votre Nextcloud grâce à notre scan de sécurité ↗
</code></pre></div></div>
<p>Créer la tâche dans un “scheduleur” cron</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
crontab -u nextcloud -e
</code></pre></div></div>
<p>Ajouter</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>*/5 * * * * /usr/bin/php7.3 -f /var/www/nextcloud/cron.php &gt; /dev/null 2&gt;&amp;1
</code></pre></div></div>
<p>Vérifier sur le site nextcloud</p>
<p><img src="/images/nextcloud-cinay.xyz.png" alt="" /></p>
<h3 id="passage-public--private">Passage public → private</h3>
<p>En mode su</p>
<p>Rechercher lapplication concernée dans la liste des applications installées</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app list -i
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
6:
description: Empty App without FTP access
id: multi_webapp__5
installed: True
label: basicblog site statique
license: GPL-3.0
name: Multi custom webapp
...
</code></pre></div></div>
<p>Basculer le flag <code class="language-plaintext highlighter-rouge">is_public: '1'</code><code class="language-plaintext highlighter-rouge">is_public: '0'</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sed -i "s/is_public: '1'/is_public: '0'/g" /etc/yunohost/apps/multi_webapp__5/settings.yml
</code></pre></div></div>
<p>Supprimer la ligne avec le flag <code class="language-plaintext highlighter-rouge">skipped_uris: /</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sed -i "/^skipped_uris/d" /etc/yunohost/apps/multi_webapp__5/settings.yml
</code></pre></div></div>
<blockquote>
<p><strong>Note: **Pour passer de **private → public</strong> , flag <code class="language-plaintext highlighter-rouge">is_public: '1'</code> et ajout dune ligne <code class="language-plaintext highlighter-rouge">skipped_uris: /</code> en avant dernière ligne du fichier <strong>/etc/yunohost/apps/multi_webapp__5/settings.yml</strong></p>
</blockquote>
<p>Régénérer le fichier de configuratio</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app ssowatconf
</code></pre></div></div>
<h3 id="désactiver-overlay-en-bas-écran">Désactiver overlay en bas écran</h3>
<p><strong>overlay en bas écran</strong><br />
Ouvrir le fichier <strong>/usr/share/ssowat/portal/assets/js/ynh_portal.js</strong> et commenter la zone suivante</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/*
// Inject portal button
var portalButton = document.createElement('a');
portalButton.setAttribute('id', 'ynh-overlay-switch');
portalButton.setAttribute('href', '/yunohost/sso/');
portalButton.setAttribute('class', 'disableAjax');
document.body.insertBefore(portalButton, null);
// Make portal button draggable, for user convenience
make_element_draggable('ynh-overlay-switch');
*/
</code></pre></div></div>
<p>Regénérer la configuration</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app ssowatconf
</code></pre></div></div>
<p><strong>sur les applications web multi…</strong></p>
<p>Il faut éditer la configuration nginx qui se trouve dans <strong>/etc/nginx/conf.d/domaine.tld.d/webapp_domaine.tld_.conf</strong> et enlever cette ligne</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Include SSOWAT user panel.
include conf.d/yunohost_panel.conf.inc;
</code></pre></div></div>
<p>A noter que de façon alternative, il est techniquement possible de remplacer le script qui charge le logo par un autre script (par exemple pour afficher un menu, ou quelques chose de plus discret, sur lensemble des apps.</p>
<p>les fichiers concernés</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/nginx/conf.d/static.cinay.xyz.d/webapp_static.cinay.xyz_.conf
/etc/nginx/conf.d/blog.cinay.xyz.d/webapp_blog.cinay.xyz_.conf
/etc/nginx/conf.d/map.cinay.xyz.d/webapp_map.cinay.xyz_.conf
</code></pre></div></div>
<p>Redémarrer nginx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart nginx
</code></pre></div></div>
<h3 id="désinstaller-monitorix">Désinstaller monitorix</h3>
<p>Liste des applications installées</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app list -i
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apps:
...
4:
description: A monitoring tools
id: monitorix
installed: True
label: Monitorix
license: GPL-2.0
name: Monitorix
...
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app remove monitorix
</code></pre></div></div>
<h3 id="27042020---désactiver-basicblog">27/04/2020 - Désactiver basicblog</h3>
<p>Il nexiste plus quun seul site statique : static.cinay.xyz<br />
Dossier : /srv/wikistatic<br />
Les liens<br />
files -&gt; /home/yannick/statique/files<br />
images -&gt; /home/yannick/statique/images<br />
_posts -&gt; /home/yannick/statique/_posts</p>
<p>Désactivation basicblog<br />
<code class="language-plaintext highlighter-rouge">sudo systemctl stop basicblog</code><br />
<code class="language-plaintext highlighter-rouge">sudo systemctl disable basicblog</code><br />
Suppression dossier : <code class="language-plaintext highlighter-rouge">sudo rm -r /srv/basicblog</code><br />
Désinstaller blog.cinay.xyz :<code class="language-plaintext highlighter-rouge">sudo yunohost app remove multi_webapp__5</code><br />
Supprimer le service : <code class="language-plaintext highlighter-rouge">sudo rm /etc/systemd/system/basicblog.service &amp;&amp; sudo systemctl daemon-reload</code></p>
<p>3 sous-domaines non utilisés : blog liens et mon</p>
<h3 id="13-juillet-2020---sauvegardes-et-synchronisations">13 juillet 2020 - Sauvegardes et synchronisations</h3>
<ul>
<li>Suppression sauvegarde via <strong>borg</strong></li>
<li>On nenvoie pas systématiquement la sauvegarde yunohost</li>
<li>Ajout sauvegarde complète via <strong>rsync</strong> avec exclusions</li>
</ul>
<p>Le fichier du schéduleur <strong>crontab</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Synchroniser le dossier "CalibreTechnique" entre le serveur de backup distant xoyaz.xyz et le serveur local cinay.xyz
15 01 * * * /usr/bin/rsync -avz -e "ssh -p 55036 -i .ssh/OVZ-STORAGE-128 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress usernl@xoyaz.xyz:/home/usernl/backup/CalibreTechnique/* /home/yunohost.multimedia/share/eBook/
# Sauvegarde des bases mysql
00 01 * * * /root/.borg/dumpmysql.sh &gt; /dev/null
# Sauvegarde complète via rsync
00 02 * * * cd /;/usr/bin/rsync -aAXv -e "ssh -p 55036 -i /home/debadm/.ssh/OVZ-STORAGE-128 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --delete --progress --exclude={dev/*,proc/*,sys/*,tmp/*,run/*,mnt/*,media/*,opt/*,lost+found} / usernl@xoyaz.xyz:/home/usernl/backup/rsync-cinay.xyz/
# Sauvegarde yunohost
## 15 01 * * * /bin/rm /home/yunohost.backup/archives/* &amp;&amp; /usr/bin/yunohost backup create -n Backup-Yunohost-cinay.xyz &gt; /dev/null
# Sauvegarde sur distant avec BorgBackup
## 00 02 * * * /root/.borg/borg-backup &gt; /dev/null
</code></pre></div></div>
<h3 id="20-juillet-2020">20 juillet 2020</h3>
<p>Supprimer</p>
<ul>
<li><strong>Calibre</strong> : <code class="language-plaintext highlighter-rouge">yunohost app remove calibreweb</code> <code class="language-plaintext highlighter-rouge">yunohost domain remove calibre.cinay.xyz</code></li>
<li><strong>Diagrams</strong> : <code class="language-plaintext highlighter-rouge">yunohost app remove diagramsnet</code></li>
<li><strong>LibreQR</strong> : <code class="language-plaintext highlighter-rouge">yunohost app remove qr</code></li>
<li><strong>shaarli</strong> : <code class="language-plaintext highlighter-rouge">yunohost app remove shaarli</code> <code class="language-plaintext highlighter-rouge">yunohost domain remove shaarli.cinay.xyz</code></li>
<li><strong>multi_webapp__2</strong> <code class="language-plaintext highlighter-rouge">yunohost app remove multi_webapp__2</code> <code class="language-plaintext highlighter-rouge">yunohost domain remove map.cinay.xyz</code></li>
<li><strong>transmission</strong> : <code class="language-plaintext highlighter-rouge">yunohost app remove transmission</code></li>
</ul>
<h3 id="nginx-warning">Nginx warning</h3>
<p>En cas davertissement</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nginx -t
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nginx: [warn] could not build optimal proxy_headers_hash, you should increase either proxy_headers_hash_max_size: 512 or proxy_headers_hash_bucket_size: 64; ignoring proxy_headers_hash_bucket_size
nginx: [warn] could not build optimal proxy_headers_hash, you should increase either proxy_headers_hash_max_size: 512 or proxy_headers_hash_bucket_size: 64; ignoring proxy_headers_hash_bucket_size
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
</code></pre></div></div>
<p>Ajouter au fichier <strong>/etc/nginx/nginx.conf</strong> , après <code class="language-plaintext highlighter-rouge">htpp {</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
</code></pre></div></div>
<p>Rechargement</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl reload nginx
</code></pre></div></div>
</div>
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2018-12-21T00: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="/2018/11/28/RaspberryPI-Raspbian-FlashDriveUSB3-RealTimeClock-EcranTactile2p8SPI.html">Raspbian Raspberry PI 3 + USB 3.0 Flash Drive FIT 32GB + "Real Time Clock" + écran tactile TFT LCD 2.8"</a></div><div class="next"><span>SUIVANT</span><a href="/2018/12/29/Archlinux-Son-Hdmi-Casque-en-un-clic.html">XFCE, changer de sortie Audio ,HDMI ou Analogique (casque), en un clic</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>