yannstatic/static/2021/10/02/HostMyServers-VPS-server32771-Installation-Yunohost-HDD-250Go.html

3467 lines
267 KiB
HTML
Raw Permalink 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>HostMyServers, server32771 Debian 10 (HDD 250Go) - yunohost INSTALLATION - YannStatic</title>
<meta name="description" content="debian">
<link rel="canonical" href="https://static.rnmkcy.eu/2021/10/02/HostMyServers-VPS-server32771-Installation-Yunohost-HDD-250Go.html"><link rel="alternate" type="application/rss+xml" title="YannStatic" href="/feed.xml">
<!-- - include head/favicon.html - -->
<link rel="shortcut icon" type="image/png" href="/assets/favicon/favicon.png"><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" ><!-- start custom head snippets --><link rel="stylesheet" href="/assets/css/expand.css">
<!-- end custom head snippets --><script>(function() {
window.isArray = function(val) {
return Object.prototype.toString.call(val) === '[object Array]';
};
window.isString = function(val) {
return typeof val === 'string';
};
window.hasEvent = function(event) {
return 'on'.concat(event) in window.document;
};
window.isOverallScroller = function(node) {
return node === document.documentElement || node === document.body || node === window;
};
window.isFormElement = function(node) {
var tagName = node.tagName;
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
};
window.pageLoad = (function () {
var loaded = false, cbs = [];
window.addEventListener('load', function () {
var i;
loaded = true;
if (cbs.length > 0) {
for (i = 0; i < cbs.length; i++) {
cbs[i]();
}
}
});
return {
then: function(cb) {
cb && (loaded ? cb() : (cbs.push(cb)));
}
};
})();
})();
(function() {
window.throttle = function(func, wait) {
var args, result, thisArg, timeoutId, lastCalled = 0;
function trailingCall() {
lastCalled = new Date;
timeoutId = null;
result = func.apply(thisArg, args);
}
return function() {
var now = new Date,
remaining = wait - (now - lastCalled);
args = arguments;
thisArg = this;
if (remaining <= 0) {
clearTimeout(timeoutId);
timeoutId = null;
lastCalled = now;
result = func.apply(thisArg, args);
} else if (!timeoutId) {
timeoutId = setTimeout(trailingCall, remaining);
}
return result;
};
};
})();
(function() {
var Set = (function() {
var add = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (data[i] === item) {
return;
}
}
this.size ++;
data.push(item);
return data;
};
var Set = function(data) {
this.size = 0;
this._data = [];
var i;
if (data.length > 0) {
for (i = 0; i < data.length; i++) {
add.call(this, data[i]);
}
}
};
Set.prototype.add = add;
Set.prototype.get = function(index) { return this._data[index]; };
Set.prototype.has = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (this.get(i) === item) {
return true;
}
}
return false;
};
Set.prototype.is = function(map) {
if (map._data.length !== this._data.length) { return false; }
var i, j, flag, tData = this._data, mData = map._data;
for (i = 0; i < tData.length; i++) {
for (flag = false, j = 0; j < mData.length; j++) {
if (tData[i] === mData[j]) {
flag = true;
break;
}
}
if (!flag) { return false; }
}
return true;
};
Set.prototype.values = function() {
return this._data;
};
return Set;
})();
window.Lazyload = (function(doc) {
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
var createNode = function(name, attrs) {
var node = doc.createElement(name), attr;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
node.setAttribute(attr, attrs[attr]);
}
}
return node;
};
var end = function(type, url) {
var s, q, qi, cbs, i, j, cur, val, flag;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
s[url] = true;
for (i = 0; i < q.length; i++) {
cur = q[i];
if (cur.urls.has(url)) {
qi = cur, val = qi.urls.values();
qi && (cbs = qi.callbacks);
for (flag = true, j = 0; j < val.length; j++) {
cur = val[j];
if (!s[cur]) {
flag = false;
}
}
if (flag && cbs && cbs.length > 0) {
for (j = 0; j < cbs.length; j++) {
cbs[j].call(context);
}
qi.load = true;
}
}
}
}
};
var load = function(type, urls, callback) {
var s, q, qi, node, i, cur,
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
for (i = 0; i < q.length; i++) {
cur = q[i];
if (_urls.is(cur.urls)) {
qi = cur;
break;
}
}
val = _urls.values();
if (qi) {
callback && (qi.load || qi.callbacks.push(callback));
callback && (qi.load && callback());
} else {
q.push({
urls: _urls,
callbacks: callback ? [callback] : [],
load: false
});
for (i = 0; i < val.length; i++) {
node = null, url = val[i];
if (s[url] === undefined) {
(type === 'js' ) && (node = createNode('script', { src: url }));
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
if (node) {
node.onload = (function(type, url) {
return function() {
end(type, url);
};
})(type, url);
(doc.head || doc.body).appendChild(node);
s[url] = false;
}
}
}
}
}
};
return {
js: function(url, callback) {
load('js', url, callback);
},
css: function(url, callback) {
load('css', url, callback);
}
};
})(this.document);
})();
</script><script>
(function() {
var TEXT_VARIABLES = {
version: '2.2.6',
sources: {
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
jquery: '/assets/js/jquery.min.js',
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
gitalk: {
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
},
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
},
site: {
toc: {
selectors: 'h1,h2,h3'
}
},
paths: {
search_js: '/assets/search.js'
}
};
window.TEXT_VARIABLES = TEXT_VARIABLES;
})();
</script>
</head>
<body>
<div class="root" data-is-touch="false">
<div class="layout--page js-page-root"><!----><div class="page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto">
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
<div class="header__title">
<div class="header__brand"><svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="478.9473684210526" viewBox="0, 0, 400,478.9473684210526"><g id="svgg"><path id="path0" d="M308.400 56.805 C 306.970 56.966,303.280 57.385,300.200 57.738 C 290.906 58.803,278.299 59.676,269.200 59.887 L 260.600 60.085 259.400 61.171 C 258.010 62.428,256.198 63.600,255.645 63.600 C 255.070 63.600,252.887 65.897,252.598 66.806 C 252.460 67.243,252.206 67.600,252.034 67.600 C 251.397 67.600,247.206 71.509,247.202 72.107 C 247.201 72.275,246.390 73.190,245.400 74.138 C 243.961 75.517,243.598 76.137,243.592 77.231 C 243.579 79.293,241.785 83.966,240.470 85.364 C 239.176 86.740,238.522 88.365,237.991 91.521 C 237.631 93.665,236.114 97.200,235.554 97.200 C 234.938 97.200,232.737 102.354,232.450 104.472 C 232.158 106.625,230.879 109.226,229.535 110.400 C 228.933 110.926,228.171 113.162,226.434 119.500 C 226.178 120.435,225.795 121.200,225.584 121.200 C 225.373 121.200,225.200 121.476,225.200 121.813 C 225.200 122.149,224.885 122.541,224.500 122.683 C 223.606 123.013,223.214 123.593,223.204 124.600 C 223.183 126.555,220.763 132.911,219.410 134.562 C 218.443 135.742,217.876 136.956,217.599 138.440 C 217.041 141.424,215.177 146.434,214.532 146.681 C 214.240 146.794,214.000 147.055,214.000 147.261 C 214.000 147.467,213.550 148.086,213.000 148.636 C 212.450 149.186,212.000 149.893,212.000 150.208 C 212.000 151.386,208.441 154.450,207.597 153.998 C 206.319 153.315,204.913 150.379,204.633 147.811 C 204.365 145.357,202.848 142.147,201.759 141.729 C 200.967 141.425,199.200 137.451,199.200 135.974 C 199.200 134.629,198.435 133.224,196.660 131.311 C 195.363 129.913,194.572 128.123,193.870 125.000 C 193.623 123.900,193.236 122.793,193.010 122.540 C 190.863 120.133,190.147 118.880,188.978 115.481 C 188.100 112.928,187.151 111.003,186.254 109.955 C 185.358 108.908,184.518 107.204,183.847 105.073 C 183.280 103.273,182.497 101.329,182.108 100.753 C 181.719 100.177,180.904 98.997,180.298 98.131 C 179.693 97.265,178.939 95.576,178.624 94.378 C 178.041 92.159,177.125 90.326,175.023 87.168 C 174.375 86.196,173.619 84.539,173.342 83.486 C 172.800 81.429,171.529 79.567,170.131 78.785 C 169.654 78.517,168.697 77.511,168.006 76.549 C 167.316 75.587,166.594 74.800,166.402 74.800 C 166.210 74.800,164.869 73.633,163.421 72.206 C 160.103 68.936,161.107 69.109,146.550 69.301 C 133.437 69.474,128.581 70.162,126.618 72.124 C 126.248 72.495,125.462 72.904,124.872 73.033 C 124.282 73.163,123.088 73.536,122.219 73.863 C 121.349 74.191,119.028 74.638,117.061 74.858 C 113.514 75.254,109.970 76.350,108.782 77.419 C 107.652 78.436,100.146 80.400,97.388 80.400 C 95.775 80.400,93.167 81.360,91.200 82.679 C 90.430 83.195,89.113 83.804,88.274 84.031 C 85.875 84.681,78.799 90.910,74.400 96.243 L 73.400 97.456 73.455 106.028 C 73.526 117.055,74.527 121.238,77.820 124.263 C 78.919 125.273,80.400 127.902,80.400 128.842 C 80.400 129.202,81.075 130.256,81.900 131.186 C 83.563 133.059,85.497 136.346,86.039 138.216 C 86.233 138.886,87.203 140.207,88.196 141.153 C 89.188 142.098,90.000 143.104,90.000 143.388 C 90.000 144.337,92.129 148.594,92.869 149.123 C 93.271 149.410,93.600 149.831,93.600 150.059 C 93.600 150.286,93.932 150.771,94.337 151.136 C 94.743 151.501,95.598 153.004,96.237 154.475 C 96.877 155.947,97.760 157.351,98.200 157.596 C 98.640 157.841,99.900 159.943,101.000 162.267 C 102.207 164.817,103.327 166.644,103.825 166.876 C 104.278 167.087,105.065 168.101,105.573 169.130 C 107.658 173.348,108.097 174.093,110.006 176.647 C 111.103 178.114,112.000 179.725,112.000 180.227 C 112.000 181.048,113.425 183.163,114.678 184.200 C 115.295 184.711,117.396 188.733,117.720 190.022 C 117.855 190.562,118.603 191.633,119.381 192.402 C 120.160 193.171,121.496 195.258,122.351 197.039 C 123.206 198.820,124.167 200.378,124.487 200.501 C 124.807 200.624,125.953 202.496,127.034 204.662 C 128.114 206.828,129.676 209.299,130.505 210.153 C 131.333 211.007,132.124 212.177,132.262 212.753 C 132.618 214.239,134.291 217.048,136.288 219.5
" href="/">YannStatic</a></div><!--<button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button>--><!-- <li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li> -->
<!-- Champ de recherche -->
<div id="searchbox" class="search search--dark" style="visibility: visible">
<div class="main">
<div class="search__header"></div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<!-- <div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div> -->
</div>
</div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json',
//searchResultTemplate: '<li><a href="https://static.rnmkcy.eu{url}">{date}&nbsp;{title}</a></li>'
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a></li>'
})
</script>
<!-- Fin déclaration champ de recherche --></div><nav class="navigation">
<ul><li class="navigation__item"><a href="/archive.html">Etiquettes</a></li><li class="navigation__item"><a href="/htmldoc.html">Documents</a></li><li class="navigation__item"><a href="/liens_ttrss.html">Liens</a></li><li class="navigation__item"><a href="/aide-jekyll-text-theme.html">Aide</a></li></ul>
</nav></div>
</header>
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
<div class="col-main cell cell--auto"><!-- start custom main top snippet --><div id="results-container" class="search-result js-search-result"></div><!-- end custom main top snippet -->
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1 style="color:Tomato;">HostMyServers, server32771 Debian 10 (HDD 250Go) - yunohost INSTALLATION</h1></header></div><meta itemprop="headline" content="HostMyServers, server32771 Debian 10 (HDD 250Go) - yunohost INSTALLATION"><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=vps">vps</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">&nbsp;2&nbsp;oct.&nbsp;&nbsp;2021</span>
<span title="Modification" style="color:#00FF7F">17&nbsp;oct.&nbsp;&nbsp;2021</span></li></ul></div><meta itemprop="datePublished" content="2021-10-17T00:00:00+02:00">
<meta itemprop="keywords" content="vps"><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="debian">debian</h2>
<p><img src="/images/debian-buster-logo1.png" alt="Debian Buster" height="40" /></p>
<p>PARAMETRES DACCES:<br />
Ladresse IPv4 du VPS est : 45.145.166.178<br />
Ladresse IPv6 du VPS est : 2a04:ecc0:8:a8:4567:4989::/64<br />
Hostname : debian-4gb-hel1-1</p>
<p>Le nom du VPS est : debian-10-cx21<br />
La clé publique <strong>debian-10-cx21.pub</strong> est transmise au gestionnaire pour la construction du serveur
Connexion SSH en “root” avec clés SSH <strong>debian-10-cx21</strong> sans mot de passe</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -i .ssh/debian-10-cx21 root@45.145.166.178
</code></pre></div></div>
<p>Créer mot de passe “root”</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>passwd
</code></pre></div></div>
<p>Désactiver init réseau cloud</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
echo "{config: disabled}" &gt; /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
</code></pre></div></div>
<p>Recréer interface réseau</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cat &gt; /etc/network/interfaces &lt;&lt; EOF
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 45.145.166.178/24
gateway 45.145.166.1
# control-alias eth0
iface eth0 inet6 static
address 2a04:ecc0:8:a8:4567:4989::1/64
gateway 2a04:ecc0:8:a8::1
EOF
</code></pre></div></div>
<p>Redémarrer le serveur</p>
<p>Réseau</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 1000
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: eth0: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 96:00:00:80:22:12 brd ff:ff:ff:ff:ff:ff
inet 45.145.166.178/32 brd 45.145.166.178 scope global dynamic eth0
valid_lft 85731sec preferred_lft 85731sec
inet6 2a04:ecc0:8:a8:4567:4989::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::9400:ff:fe80:2212/64 scope link
valid_lft forever preferred_lft forever
</code></pre></div></div>
<p>Noyau et OS : <code class="language-plaintext highlighter-rouge">uname -a</code></p>
<p>Linux debian-4gb-hel1-1 4.19.0-12-amd64 #1 SMP Debian 4.19.152-1 (2020-10-18) x86_64 GNU/Linux</p>
<p>Paramétrage fuseau <strong>Europe/Paris</strong> : <code class="language-plaintext highlighter-rouge">dpkg-reconfigure tzdata</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Current default time zone: 'Europe/Paris'
Local time is now: Sun Nov 22 08:06:42 CET 2020.
Universal Time is now: Sun Nov 22 07:06:42 UTC 2020.
</code></pre></div></div>
<p>Vérifier lheure</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>timedatectl status
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Local time: Sun 2020-11-22 08:45:34 CET
Universal time: Sun 2020-11-22 07:45:34 UTC
RTC time: Sun 2020-11-22 07:45:35
Time zone: Europe/Paris (CET, +0100)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
</code></pre></div></div>
<p>Hostname</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>hostnamectl
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Static hostname: debian-4gb-hel1-1
Icon name: computer-vm
Chassis: vm
Machine ID: 5e93c746b78b49c5a61470c448d04423
Boot ID: 513fff3bb1db43a392217d19105e2c2d
Virtualization: kvm
Operating System: Debian GNU/Linux 10 (buster)
Kernel: Linux 4.19.0-12-amd64
Architecture: x86-64
</code></pre></div></div>
<p><strong>Locales</strong> reconfiguration pour le français par défaut</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dpkg-reconfigure locales
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[*] en_US.UTF-8 UTF-8
[*] fr_FR.UTF-8 UTF-8
</code></pre></div></div>
<h2 id="yunohost">Yunohost</h2>
<p><img src="/images/yunohost.png" alt="" width="30" /></p>
<h3 id="installation">Installation</h3>
<p>Une fois que vous avez accès à votre serveur (directement ou par SSH)<br />
vous pouvez installer YunoHost en exécutant cette commande en tant que root :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt update &amp;&amp; apt upgrade
apt install curl
curl https://install.yunohost.org | bash
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>...]
<span class="o">[</span> OK <span class="o">]</span> YunoHost installation completed <span class="o">!</span>
<span class="o">===============================================================================</span>
You should now proceed with Yunohost post-installation. This is where you will
be asked <span class="k">for</span> :
- the main domain of your server <span class="p">;</span>
- the administration password.
You can perform this step :
- from the <span class="nb">command </span>line, by running <span class="s1">'yunohost tools postinstall'</span> as root
- or from your web browser, by accessing :
- https://45.145.166.178/ <span class="o">(</span>global IP, <span class="k">if </span>you<span class="s1">'re on a VPS)
If this is your first time with YunoHost, it is strongly recommended to take
time to read the administator documentation and in particular the sections
'</span>Finalizing your setup<span class="s1">' and '</span>Getting to know YunoHost<span class="s1">'. It is available at
the following URL : https://yunohost.org/admindoc
===============================================================================
</span></code></pre></div></div>
<h3 id="post-installation-yanfispace">Post-installation (yanfi.space)</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost tools postinstall
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Main domain: yanfi.space
[...]
Warning: The ssh configuration has been manually modified, but you need to explicitly specify category 'ssh' with --force to actually apply the changes.
Success! YunoHost is now configured
Warning: The post-install completed! To finalize your setup, please consider:
- adding a first user through the 'Users' section of the webadmin (or 'yunohost user create &lt;username&gt;' in command-line);
- diagnose potential issues through the 'Diagnosis' section of the webadmin (or 'yunohost diagnosis run' in command-line);
- reading the 'Finalizing your setup' and 'Getting to know Yunohost' parts in the admin documentation: https://yunohost.org/admindoc.
</code></pre></div></div>
<blockquote>
<p>Le mot de passe root remplacé par celui de ladmin yunohost</p>
</blockquote>
<h3 id="ssh-admin">SSH (admin)</h3>
<p><img src="/images/ssh-logo2.png" alt="" width="50" /></p>
<p>Autoriser admin à se connecter SSH</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir /home/admin/.ssh
cp /root/.ssh/authorized_keys /home/admin/.ssh/
chown admin.1007 -R /home/admin/.ssh
</code></pre></div></div>
<p>Modification SSH pour être conforme à linstallation yunohost mise à part lutilisation dun fichier clé qui nest pas pris en compte dans la gestion SSH Yunohost</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/ssh/sshd_config
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># This configuration has been automatically generated
# by YunoHost
Protocol 2
Port 55127
ListenAddress ::
ListenAddress 0.0.0.0
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
# ##############################################
# Stuff recommended by Mozilla "modern" compat'
# https://infosec.mozilla.org/guidelines/openssh
# ##############################################
# By default use "modern" Mozilla configuration
# Keys, ciphers and MACS
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
# LogLevel VERBOSE logs user's key fingerprint on login.
# Needed to have a clear audit track of which key was using to log in.
SyslogFacility AUTH
LogLevel VERBOSE
# #######################
# Authentication settings
# #######################
# Comment from Mozilla about the motivation behind disabling root login
#
# Root login is not allowed for auditing reasons. This is because it's difficult to track which process belongs to which root user:
#
# On Linux, user sessions are tracking using a kernel-side session id, however, this session id is not recorded by OpenSSH.
# Additionally, only tools such as systemd and auditd record the process session id.
# On other OSes, the user session id is not necessarily recorded at all kernel-side.
# Using regular users in combination with /bin/su or /usr/bin/sudo ensure a clear audit track.
LoginGraceTime 120
PermitRootLogin no
StrictModes yes
PubkeyAuthentication yes
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes
# Change to no to disable tunnelled clear text passwords
# (i.e. everybody will need to authenticate using ssh keys)
PasswordAuthentication no
# Post-login stuff
Banner /etc/issue.net
PrintMotd no
PrintLastLog yes
ClientAliveInterval 60
AcceptEnv LANG LC_*
# Disallow user without ssh or sftp permissions
AllowGroups ssh.main sftp.main ssh.app sftp.app admins root
# Allow users to create tunnels or forwarding
AllowTcpForwarding yes
AllowStreamLocalForwarding yes
PermitTunnel yes
PermitUserRC yes
# SFTP stuff
Subsystem sftp internal-sftp
# Apply following instructions to user with sftp perm only
Match Group sftp.main,!ssh.main
ForceCommand internal-sftp
# We can't restrict to /home/%u because the chroot base must be owned by root
# So we chroot only on /home
# See https://serverfault.com/questions/584986/bad-ownership-or-modes-for-chroot-directory-component
ChrootDirectory /home
# Forbid SFTP users from using their account SSH as a VPN (even if SSH login is disabled)
AllowTcpForwarding no
AllowStreamLocalForwarding no
PermitTunnel no
# Disable .ssh/rc, which could be edited (e.g. from Nextcloud or whatever) by users to execute arbitrary commands even if SSH login is disabled
PermitUserRC no
Match Group sftp.app,!ssh.app
ForceCommand internal-sftp
ChrootDirectory %h
AllowTcpForwarding no
AllowStreamLocalForwarding no
PermitTunnel no
PermitUserRC no
PasswordAuthentication yes
# root login is allowed on local networks
# It's meant to be a backup solution in case LDAP is down and
# user admin can't be used...
# If the server is a VPS, it's expected that the owner of the
# server has access to a web console through which to log in.
Match Address 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,169.254.0.0/16,fe80::/10,fd00::/8
PermitRootLogin yes
</code></pre></div></div>
<p>Relancer openSSH</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart sshd
</code></pre></div></div>
<p>Ouvrir le port 55127 et fermer le port 22</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost firewall allow TCP 55127
yunohost firewall disallow TCP 22
</code></pre></div></div>
<p>Accès utilisateur depuis le poste distant avec la clé privée</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh admin@45.145.166.178 -p 55127 -i /home/yannick/.ssh/debian-10-cx21
</code></pre></div></div>
<p>Installer utilitaires</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install rsync curl tmux jq figlet git dnsutils tree -y
</code></pre></div></div>
<p>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-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ___ _
___ ___ ___ ___ __ __ __|_ <span class="o">)</span>/ | ___ ___ ___ ___
|___||___||___||___| / _|<span class="se">\ \ </span>/ / / | | |___||___||___||___|
<span class="se">\_</span>_|/_<span class="se">\_\/</span>___||_|
_ _ __ _ _ _ / _|<span class="o">(</span>_<span class="o">)</span> ___ _ __ __ _ __ ___
| <span class="o">||</span> |/ _<span class="sb">`</span> <span class="o">||</span> <span class="s1">' \ | _|| | _ (_-&lt;| '</span>_ <span class="se">\/</span> _<span class="sb">`</span> |/ _|/ <span class="nt">-_</span><span class="o">)</span>
<span class="se">\_</span>, |<span class="se">\_</span>_,_||_||_||_| _|_|<span class="o">(</span>_<span class="o">)</span>/__/| .__/<span class="se">\_</span>_,_|<span class="se">\_</span>_|<span class="se">\_</span>__|
|__/ _ __ _ _ _ / _|<span class="o">(</span>_<span class="o">)</span> _|_| ___ | |_
| <span class="o">||</span> |/ _<span class="sb">`</span> <span class="o">||</span> <span class="s1">' \ | _|| | _ | '</span> <span class="se">\ </span>/ <span class="nt">-_</span><span class="o">)</span>| _|
<span class="se">\_</span>, |<span class="se">\_</span>_,_||_||_||_| |_|<span class="o">(</span>_<span class="o">)</span>|_||_|<span class="se">\_</span>__| <span class="se">\_</span>_|
|__/<span class="o">(</span>_<span class="o">)</span> _ _ __ _ _ _ ___ _ _
/ _|| <span class="o">||</span> <span class="s1">' \ / _` || || | _ / -_)| || |
\__||_||_||_|\__,_| \_, |(_)\___| \_,_|
|__/
</span></code></pre></div></div>
<p>Autoriser utilisateur à accéder aux journaux systemd</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo usermod -a -G systemd-journal $USER
</code></pre></div></div>
<h3 id="ssh---alerte-par-messagerie">SSH - Alerte par messagerie</h3>
<p><strong>alerte email quand une connexion ssh est réussie</strong></p>
<p class="warning">Attention: selon les commentaires, cela ne fonctionnera pas si lutilisateur crée un fichier nommé <code class="language-plaintext highlighter-rouge">~/.ssh/rc</code></p>
<p>Modifier ou créer <code class="language-plaintext highlighter-rouge">/etc/ssh/sshrc</code> avec le contenu suivant:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DESTINATAIRE="vps@ciany.eu"
VPHOST=$(hostname -f)
DATE=$(date "+%d.%m.%Y--%Hh%Mm")
IP=$(echo $SSH_CONNECTION | awk '{print $1}')
#IP=`echo $SSH_CONNECTION | cut -d " " -f 1`
LOCALISATION=$(curl -s ipinfo.io/"$IP" | jq -r '[.country, .city] | join(", ")')
REVERSE=$(dig -x $IP +short)
echo "Connexion de ${USER} sur $VPHOST
IP de connexion: ${IP}
Localisation appelant: ${LOCALISATION}
ReverseDNS: ${REVERSE}
Date: ${DATE}
" | mail -s "Connexion de ${USER} sur $VPHOST" $DESTINATAIRE
</code></pre></div></div>
<h3 id="sshfs-partage-xoyazxyz">SSHFS partage xoyaz.xyz</h3>
<p><img src="/images/sshfs-logo.png" alt="" width="70" /></p>
<p><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>Le but, créer un accès réseau sur un autre serveur pour les gros volumes de fichiers (musique, livres, etc…)<br />
Le dossier local <strong>/opt/sshfs/</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkdir -p /opt/sshfs
</code></pre></div></div>
<p>Il faut créer une liaison réseau sécurisée entre <strong>cinay.eu ← → xoyaz.xyz</strong></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><strong>Partage avec serveur hms.xoyaz.xyz</strong> : Clé privée <strong>hms-sto-250</strong> <br />
Droits : <code class="language-plaintext highlighter-rouge">chmod 600 /home/admin/.ssh/hms-sto-250</code></p>
<p><strong>Montage 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 userhms@hms.xoyaz.xyz:/home/userhms/sshfs /opt/sshfs -C -p 55051 -oIdentityFile=/home/admin/.ssh/hms-sto-250
</code></pre></div></div>
<blockquote>
<p>NOTE: Il faut mettre ladresse IP du serveur , si les domaines peuvent ne pas être “résolus”</p>
</blockquote>
<p>Après vérification , <code class="language-plaintext highlighter-rouge">ls /opt/sshfs</code> , déconnexion <code class="language-plaintext highlighter-rouge">fusermount -u /opt/sshfs</code></p>
<p><strong>Montage auto</strong><br />
Ajouter la ligne suivante au fichier <code class="language-plaintext highlighter-rouge">/etc/fstab</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>userhms@hms.xoyaz.xyz:/home/userhms/sshfs /opt/sshfs fuse.sshfs _netdev,identityfile=/home/admin/.ssh/hms-sto-250,allow_other,port=55051 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>
<h3 id="domaines-et-dns">Domaines et DNS</h3>
<p><img src="/images/dns-logo.png" alt="" width="50" /></p>
<p>Configuration DNS domaine par défaut <strong>yanfi.space</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain dns-conf yanfi.space
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; Basic ipv4/ipv6 records
@ 3600 IN A 45.145.166.178
@ 3600 IN AAAA 2a04:ecc0:8:a8:4567:4989::1
; XMPP
_xmpp-client._tcp 3600 IN SRV 0 5 5222 yanfi.space.
_xmpp-server._tcp 3600 IN SRV 0 5 5269 yanfi.space.
muc 3600 IN CNAME @
pubsub 3600 IN CNAME @
vjud 3600 IN CNAME @
xmpp-upload 3600 IN CNAME @
; Mail
@ 3600 IN MX 10 yanfi.space.
@ 3600 IN TXT "v=spf1 a mx -all"
mail._domainkey 3600 IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM7ja2oZ0efNg8WWoRY82kneRiJOciFAgyBfaDpNzRQdaphq082256m6Ol9tWEqCjWakO5nmvP03s+zw53lZoUfZyY4FE58AAesHszSyvVYhCz7uSfEijD4snvIYSqkuFvRNLv2WCYPQFelx9VPl5095f+8X0Y8dx4H2TvGGqsUQIDAQAB"
_dmarc 3600 IN TXT "v=DMARC1; p=none"
; Extra
* 3600 IN A 45.145.166.178
* 3600 IN AAAA 2a04:ecc0:8:a8:4567:4989::1
@ 3600 IN CAA 128 issue "letsencrypt.org"
</code></pre></div></div>
<p>Se connecter à lespace client du site OVH : <strong>Web cloud → Domaines → xoyize.xyz → Zone DNS</strong><br />
Cliquer sur <strong>“Modifier en mode textuel”</strong>, garder les 4 premières lignes :<br />
<img src="/images/dns-ovh-zone.png" alt="" width="600" /><br />
puis effacer tout ce quil y a en-dessous, et le remplacer par la configuration donnée par votre serveur ( <code class="language-plaintext highlighter-rouge">yunohost domain dns-conf</code>)</p>
<p>Création et configuration DNS domaine <strong>yanfi.net</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add yanfi.net
</code></pre></div></div>
<p>Les dns</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain dns-conf yanfi.net
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; Basic ipv4/ipv6 records
@ 3600 IN A 45.145.166.178
@ 3600 IN AAAA 2a04:ecc0:8:a8:4567:4989::1
; XMPP
_xmpp-client._tcp 3600 IN SRV 0 5 5222 yanfi.net.
_xmpp-server._tcp 3600 IN SRV 0 5 5269 yanfi.net.
muc 3600 IN CNAME @
pubsub 3600 IN CNAME @
vjud 3600 IN CNAME @
xmpp-upload 3600 IN CNAME @
; Mail
@ 3600 IN MX 10 yanfi.net.
@ 3600 IN TXT "v=spf1 a mx -all"
mail._domainkey 3600 IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7jDcuICl4E9fLUhdum1TW7Pxj+pKDrn7np1nu4umYuZd7qVt69JGjtF4RvBGOASxguG1uVZLoBBYPgA8sZmmbT1Laf7g74YQm+i345yjzklT96aCJu1PvZMosvzMOBfbx6N08Nav5Rp++PTuMHFXhyDmJMr/c2/epVWm4eXbdAwIDAQAB"
_dmarc 3600 IN TXT "v=DMARC1; p=none"
; Extra
* 3600 IN A 45.145.166.178
* 3600 IN AAAA 2a04:ecc0:8:a8:4567:4989::1
@ 3600 IN CAA 128 issue "letsencrypt.org"
</code></pre></div></div>
<p>Création et configuration DNS domaine <strong>cinay.eu</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add cinay.eu
</code></pre></div></div>
<p>Les dns</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain dns-conf cinay.eu
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; Basic ipv4/ipv6 records
@ 3600 IN A 45.145.166.178
@ 3600 IN AAAA 2a04:ecc0:8:a8:4567:4989::1
; XMPP
_xmpp-client._tcp 3600 IN SRV 0 5 5222 cinay.eu.
_xmpp-server._tcp 3600 IN SRV 0 5 5269 cinay.eu.
muc 3600 IN CNAME @
pubsub 3600 IN CNAME @
vjud 3600 IN CNAME @
xmpp-upload 3600 IN CNAME @
; Mail
@ 3600 IN MX 10 cinay.eu.
@ 3600 IN TXT "v=spf1 a mx -all"
mail._domainkey 3600 IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDn4KD67wSLqb4ACbBdFniSYnPkbNHAjCdah4fYFuyVkefSW5lZjmwPiZ26GJpf1gBT4/kUc5XtRdXosCDJuGsmfq0JwA7813Gmn00wNIuOGQ5WglGSvpm73iVomF/psI/+ElbA0TX0T8babIciq+jdA7g4ZhJ/zUX93oAAOoqaOQIDAQAB"
_dmarc 3600 IN TXT "v=DMARC1; p=none"
; Extra
* 3600 IN A 45.145.166.178
* 3600 IN AAAA 2a04:ecc0:8:a8:4567:4989::1
@ 3600 IN CAA 128 issue "letsencrypt.org"
</code></pre></div></div>
<h3 id="reverse-dns-hetzner-vps-cx21">Reverse DNS HETZNER VPS CX21</h3>
<p>Se connecter en console sur lhébergeur du VPS et dans Networking , modifier les reverses DNS</p>
<p>Mise à jour reverse DNS IPV4 IPV6<br />
45.145.166.178 → yanfi.space<br />
2a04:ecc0:8:a8:4567:4989::1 → yanfi.space</p>
<h3 id="certificats-ssl">Certificats SSL</h3>
<p><img src="/images/letsencrypt-logo1.png" alt="" /></p>
<p>Installer un certificat Lets Encrypt en ligne de commande</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain cert-install --no-checks # yanfi.space
yunohost domain cert-install yanfi.net --no-checks
yunohost domain cert-install cinay.eu --no-checks
</code></pre></div></div>
<h3 id="utilisateur-yann">Utilisateur yann</h3>
<p>Création utilisateur yann</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost user create yann
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>First name: yann
Last name: cinayeu
E-mail address: yann@cinay.eu
You are now about to define a new user password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to a variation of characters (uppercase, lowercase, digits and special characters).
Password:
Confirm password:
Success! User created
fullname: yann cinayeu
mail: yann@cinay.eu
username: yann
</code></pre></div></div>
<h3 id="historique-de-la-ligne-de-commande">Historique de la ligne de commande</h3>
<p>Ajoutez la recherche dhistorique de la ligne de commande au terminal.
Tapez un début de commande précédent, puis utilisez shift + up (flèche haut) pour rechercher lhistorique filtré avec le début de la commande.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Global, tout utilisateur</span>
<span class="nb">echo</span> <span class="s1">'"\e[1;2A": history-search-backward'</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/inputrc
<span class="nb">echo</span> <span class="s1">'"\e[1;2B": history-search-forward'</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/inputrc
</code></pre></div></div>
<h3 id="script-ssh_rc_bash">Script ssh_rc_bash</h3>
<p><img src="/images/bash-shell-logo.png" alt="" width="50" /></p>
<blockquote>
<p><strong>ATTENTION!!! Les scripts sur connexion peuvent poser des problèmes pour des appels externes autres que ssh</strong></p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://static.xoyaz.xyz/files/ssh_rc_bash
chmod +x ssh_rc_bash # rendre le bash exécutable
./ssh_rc_bash # exécution
</code></pre></div></div>
<p><img src="/images/cx21.png" alt="" /></p>
<h2 id="applications">Applications</h2>
<p class="info">La plupart des commandes sont exécutées en mode “su”</p>
<h3 id="nextcloud-nextcloud">Nextcloud (/nextcloud)</h3>
<p><img src="/images/nextcloud_logo.png" alt="" width="70" /></p>
<p>Sur le domaine cinay.eu admin, yann</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/nextcloud_ynh --debug
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[...]
Choose a domain for Nextcloud (default: cinay.eu):
Choose a path for Nextcloud (default: /nextcloud):
Choose the Nextcloud administrator (must be an existing YunoHost user): yann
Access the users home folder from Nextcloud? [yes | no] (default: no): no
[...]
</code></pre></div></div>
<p>Dans les paramètres fichier de nextcloud , activer laffichage des fichiers masqués</p>
<h4 id="activer-les-applications">Activer les applications</h4>
<p>Activer les applications <strong>Calendar</strong>, <strong>Contacts</strong> et <strong>Notes</strong> sur nextcloud</p>
<h4 id="paramètres-de-base">Paramètres de base</h4>
<ul>
<li>Paramètres de base
<ul>
<li>Serveur e-mail</li>
</ul>
</li>
<li>Personnaliser lapparence
<ul>
<li>Logo</li>
<li>Image de connexion</li>
</ul>
</li>
</ul>
<h4 id="calendrier-et-contacts-android-et-thunderbird">Calendrier et contacts (android et thunderbird)</h4>
<p>Paramétrage <strong>OpenSync</strong> android<br />
Connexion avec le lien https://cinay.eu/nextcloud/remote.php/dav (login+mdp)<br />
<img src="/images/opensync-1.png" alt="" height="300" /> <img src="/images/opensync-2.png" alt="" height="300" /></p>
<p>Paramétrer les applications qui utilisent le calendrier et les contacts<br />
<strong>Contacts</strong> , <strong>acalendar</strong> et <strong>Tâches</strong><br />
<img src="/images/opensync-3.png" alt="" height="300" /> <img src="/images/opensync-4.png" alt="" height="300" /> <img src="/images/opensync-5.png" alt="" height="300" /></p>
<p>Paramétrage agenda <strong>Thunderbird</strong><br />
<img src="/images/thb001.png" alt="" width="300" /> <img src="/images/thb002.png" alt="" width="300" /><br />
<img src="/images/thb003.png" alt="" width="300" /> <img src="/images/thb004.png" alt="" width="300" />
<img src="/images/thb005.png" alt="" width="300" /><br />
Se désabonner de lancien agenda cinay.xyz</p>
<p>Paramétrage contacts <strong>Thunderbird</strong><br />
Outils → Préférences des modules → TbSync <br />
Dans lapplication<br />
Actions sur les comptes → Ajouter un nouveau compte → Caldav &amp; Carddav<br />
<img src="/images/tbsync01.png" alt="" width="300" /> <img src="/images/tbsync02.png" alt="" width="300" /> <br />
<img src="/images/tbsync03.png" alt="" width="300" /> <br />
<img src="/images/tbsync04.png" alt="" width="300" /> <br />
Synchronisation toutes les heures pour les contacts</p>
<p>Liens caldav carddav sur thunderbird (yann) <br />
https://cinay.eu/nextcloud/remote.php/dav/calendars/yann/personal/<br />
https://cinay.eu/nextcloud/remote.php/dav/addressbooks/users/yann/contacts/</p>
<h4 id="compte-nextcloud-sur-les-postes-clients-de-type-pc">Compte nextcloud sur les postes clients de type PC</h4>
<p>Ajout du compte https://cinay.eu/nextcloud sur les clients nextcloud <br />
Synchronisations:</p>
<ul>
<li>~/.keepassx → Home/.keepassx (créer le dossier)</li>
<li>~/media/Notes → Notes (créer le dossier)</li>
</ul>
<h4 id="compte-nextcloud-sur-android">Compte nextcloud sur android</h4>
<p>Application nextcloud installée<br />
Se connecter https://cinay.eu/nextcloud et vérifier la création du compte<br />
<img src="/images/ncinayeu001.png" alt="" height="300" /></p>
<p>Synchroniser le fichier de mot de passe avec lapplication keepass<br />
<img src="/images/ncinayeu002.png" alt="" height="300" /> <img src="/images/ncinayeu003.png" alt="" height="300" /><br />
<img src="/images/ncinayeu004.png" alt="" width="200" /></p>
<blockquote>
<p>Corriger lavertissement <font color="red">« La limite de mémoire PHP est inférieure à la valeur recommandée de 512 Mo »</font><br />
Augmenter la mémoire : <code class="language-plaintext highlighter-rouge">memory_limit = 512M</code> dans le fichier <code class="language-plaintext highlighter-rouge">/etc/php/7.3/fpm/php.ini</code> <br />
Relancer <code class="language-plaintext highlighter-rouge">sudo systemctl restart php7.3-fpm</code></p>
</blockquote>
<h3 id="tiny-tiny-rss-ttrss">Tiny Tiny RSS (/ttrss)</h3>
<p><img src="/images/ttrss-logo.png" alt="image" width="50px" /><br />
<em>Tiny Tiny RSS (ttrss) est un agrégateur de flux RSS et Atom libre sous licence libre GNU GPL v3</em></p>
<p>Installation en mode de commande (su)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install ttrss
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Choose a domain for Tiny-Tiny-RSS (default: cinay.eu):
Choose a path for Tiny-Tiny-RSS (default: /ttrss):
Success! Installation completed
</code></pre></div></div>
<p>Mise à jour</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app upgrade ttrss -u https://github.com/YunoHost-Apps/ttrss_ynh/tree/testing --debug
</code></pre></div></div>
<p>Personnaliser le CSS , configuration</p>
<p><img src="/images/ttrss-css1.png" alt="" width="400" /></p>
<p>Ajout du contenu suivant dans la feuille de style</p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">body</span><span class="nc">.flat.ttrss_main</span> <span class="nf">#headlines-frame</span> <span class="nc">.hl.Unread</span><span class="nd">:not</span><span class="o">(</span><span class="nc">.active</span><span class="o">)</span><span class="nd">:not</span><span class="o">(</span><span class="nc">.Selected</span><span class="o">),</span>
<span class="nt">body</span><span class="nc">.flat.ttrss_main</span> <span class="nf">#headlines-frame</span> <span class="nc">.cdm.expandable.Unread</span><span class="nd">:not</span><span class="o">(</span><span class="nc">.active</span><span class="o">)</span><span class="nd">:not</span><span class="o">(</span><span class="nc">.Selected</span><span class="o">)</span> <span class="p">{</span>
<span class="nl">background</span><span class="p">:</span> <span class="m">#696969</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p><img src="/images/ttrss-css2.png" alt="" width="400" /><br />
Puis cliquer <strong>Save and reload</strong></p>
<h3 id="shaarli">Shaarli</h3>
<p><img src="/images/shaarli_logo.png" alt="" width="70" /></p>
<p>Installation</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/shaarli_ynh/tree/testing
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>domaine : yanfi.space
racine : /shaarli
utilisateur admin : yann
Mp admin : idem mp yann
Site publique: oui
</code></pre></div></div>
<p>Basculer lapplication de privée en publique</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sed -i "s/is_public\: '0'/is_public\: '1'/g" /etc/yunohost/apps/shaarli/settings.yml
</code></pre></div></div>
<p>Regénérer la configuration</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app ssowatconf
</code></pre></div></div>
<h3 id="staticcinayeu">static.cinay.eu</h3>
<p>En mode su</p>
<p>Créer le domaine static.cinay.eu et les certificats</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add static.cinay.eu
yunohost domain cert-install static.cinay.eu --no-checks
</code></pre></div></div>
<p>Installer lapplication <code class="language-plaintext highlighter-rouge">Custom web app</code> sur le domaine static.cinay.eu</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/my_webapp_ynh/tree/testing --debug
</code></pre></div></div>
<p>Domaine : static.cinay.eu<br />
Racine : /<br />
Utilisateur : yann<br />
Create a database: no<br />
Site publique: yes<br />
SFTP : no + mot de passe</p>
<p>Accès au site https://static.cinay.eu</p>
<p>Le dossier <strong>/opt/sshfs/static/</strong> contient le site statique qui est issu dune synchronisation dun conteneur debian sur un ordinateur archlinux avec jekyll comme générateur</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-r</span> /var/www/my_webapp/www/ <span class="c"># supprimer dossier web </span>
<span class="nb">chown </span>my_webapp.my_webapp <span class="nt">-R</span> /var/www/my_webapp
<span class="nb">ln</span> <span class="nt">-s</span> /opt/sshfs/static /var/www/my_webapp/www <span class="c"># lien et droits my_webapp</span>
<span class="nb">ln</span> <span class="nt">-s</span> /opt/sshfs/static/htmldoc /var/www/my_webapp/www/htmldoc
</code></pre></div></div>
<p>Modifier létiquette <code class="language-plaintext highlighter-rouge">my_webapp</code> (static.cinay.eu)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label my_webapp 'Statique static.cinay.eu'
</code></pre></div></div>
<h3 id="cinayeusite">cinay.eu/site</h3>
<p>Accès à des liens tel que “Diceware”<br />
<em>Le diceware, ou méthode du lancer de dés selon l Office québécois de la langue française, est, en cryptologie, une méthode employée pour créer des phrases secrètes, des mots de passe et dautres variables cryptographiques en utilisant un dé ordinaire à six faces comme générateur de nombres aléatoires physique.</em></p>
<p>Installer lapplication <code class="language-plaintext highlighter-rouge">Custom web app</code> sans sftp sur cinay.eu/site</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/my_webapp_ynh/tree/testing --debug
</code></pre></div></div>
<p>Application id: my_webapp__2</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-r</span> /var/www/my_webapp__2/www <span class="c"># supprimer dossier web </span>
<span class="nb">chown </span>my_webapp__2.my_webapp__2 <span class="nt">-R</span> /var/www/my_webapp__2
<span class="nb">ln</span> <span class="nt">-s</span> /opt/sshfs/www /var/www/my_webapp__2/www <span class="c"># lien et droits my_webapp</span>
</code></pre></div></div>
<p>Modifier le fichier de configuration <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/cinay.eu.d/my_webapp__2.conf</code> pour lister le contenu dun répertoire</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> # Deny access to hidden files and directories
# location ~ ^/site/(.+/|)\.(?!well-known\/) {
# deny all;
# }
fancyindex on; # Enable fancy indexes.
fancyindex_exact_size off; # Output human-readable file sizes.
</code></pre></div></div>
<p>Redémarrer le serveur nginx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart nginx
</code></pre></div></div>
<p>Modifier létiquette <code class="language-plaintext highlighter-rouge">my_webapp__2</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label my_webapp__2 'Cartographie Diceware'
</code></pre></div></div>
<p>https://cinay.eu/site</p>
<p><img src="/images/cinay.eu_site.png" alt="" width="500" /></p>
<h3 id="cartes---mapcinayeu">Cartes - map.cinay.eu</h3>
<p>En mode su</p>
<p>Créer le domaine map.cinay.eu et les certificats</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add map.cinay.eu
yunohost domain cert-install map.cinay.eu --no-checks
</code></pre></div></div>
<p>Installer lapplication <code class="language-plaintext highlighter-rouge">Custom web app</code> sur le domaine map.cinay.eu</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/my_webapp_ynh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Choose the domain where this app should be installed [cinay.eu | gitea.cinay.eu | map.cinay.eu | static.cinay.eu | yanfi.net | yanfi.space | searx.yanfi.space | zic.yanfi.space] (default: yanfi.space): map.cinay.eu
Choose the path where this app should be installed (default: /site): /
Do you need a SFTP access? [yes | no] (default: yes): no
Choose an administration password for this app:
Should this app be exposed to anonymous visitors? [yes | no] (default: yes):
Do you need a MySQL database? [yes | no] (default: no):
[...]
Info: [####################] &gt; Installation of my_webapp__3 completed
Success! Installation completed
</code></pre></div></div>
<p>Accès au site https://map.cinay.eu</p>
<p>Le dossier <strong>/opt/sshfs/www/osm-new/</strong> contient le site cartographique basé sur leaflet</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-r</span> /var/www/my_webapp__3/www/ <span class="c"># supprimer dossier web </span>
<span class="nb">chown </span>my_webapp__3.my_webapp__3 <span class="nt">-R</span> /var/www/my_webapp__3
<span class="nb">ln</span> <span class="nt">-s</span> /opt/sshfs/www/osm-new /var/www/my_webapp__3/www <span class="c"># lien et droits my_webapp__3</span>
</code></pre></div></div>
<p>Modifier létiquette <code class="language-plaintext highlighter-rouge">my_webapp__3</code> (map.cinay.eu)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label my_webapp__3 'Cartes map.cinay.eu'
</code></pre></div></div>
<h3 id="gitea-giteacinayeu">Gitea (gitea.cinay.eu)</h3>
<p><a href="https://github.com/YunoHost-Apps/gitea_ynh"><img src="/images/gitea-logo.png" alt="" width="70" /></a></p>
<p>Ajout domaine et certificats gitea.cinay.eu</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add gitea.cinay.eu
yunohost domain cert-install gitea.cinay.eu --no-checks
</code></pre></div></div>
<p>Installation à partir de github, on clône le dépôt</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/YunoHost-Apps/gitea_ynh.git
</code></pre></div></div>
<p>Blocage sur fail2ban à linstallation <br />
Commenter la mise en place FAIL2BAN</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano gitea_ynh/scripts/install
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># SETUP FAIL2BAN
#ynh_script_progression --message="Configuring fail2ban..."
#ynh_add_fail2ban_config --logpath "/var/log/$app/gitea.log" --failregex ".*Failed authentication attempt for .* from &lt;HOST&gt;" --max_retry 5
</code></pre></div></div>
<p>Installer gitea</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install gitea_ynh
</code></pre></div></div>
<p>Fail2ban , règle qui nest pas ajouté</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ynh_add_fail2ban_config --logpath /var/log/gitea/gitea.log --failregex '.*Failed authentication attempt for .* from &lt;HOST&gt;' --max_retry 5
</code></pre></div></div>
<p>Modifier létiquette <code class="language-plaintext highlighter-rouge">gitea</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label gitea 'Gitea gitea.cinay.eu'
</code></pre></div></div>
<h3 id="searx-searxyanfispace">Searx (searx.yanfi.space)</h3>
<p><a href="https://github.com/YunoHost-Apps/searx_ynh"><img src="/images/Searx_logo.png" alt="" width="50" /></a></p>
<p>Ajout domaine et certificats searx.yanfi.space</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost domain add searx.yanfi.space
sudo yunohost domain cert-install searx.yanfi.space --no-checks
</code></pre></div></div>
<p><strong>Searx - docker</strong><br />
Les procédures dinstallation, voir le lien <a href="/2018/05/03/Searx-Metamoteur-Recherche-Libre.html">Searx (métamoteur de recherche libre)</a></p>
<p>Limage du docker est <a href="https://hub.docker.com/r/searx/searx">searx/searx</a> (basée sur <a href="https://github.com/searx/searx">github.com/searx/searx</a>).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /home/admin
docker pull searx/searx
docker images
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>REPOSITORY TAG IMAGE ID CREATED SIZE
searx/searx latest 096886989dad 6 hours ago 161MB
</code></pre></div></div>
<p>La méthode la plus simple pour déployer un conteneur en tant que service consiste à créer le conteneur sil nexiste pas avec un nom donné et ensuite de mapper chacune des opérations de docker (démarrage et arrêt) aux commandes de service du système.</p>
<p>Une fois que nous avons créé ce conteneur, nous pouvons le démarrer, larrêter et le redémarrer en utilisant les commandes habituelles du docker en indiquant le nom du conteneur (<code class="language-plaintext highlighter-rouge">docker stop searx</code>, <code class="language-plaintext highlighter-rouge">docker start searx</code>, <code class="language-plaintext highlighter-rouge">docker restart searx</code>).</p>
<p>Créer un nouveau fichier dunité systemd <code class="language-plaintext highlighter-rouge">searx.service</code> avec la description du service dans <code class="language-plaintext highlighter-rouge">/etc/systemd/system/</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/systemd/system/searx.service
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
Description=searx container
After=docker.service
Wants=network-online.target docker.socket
Requires=docker.socket
[Service]
Restart=always
ExecStartPre=/bin/bash -c "/usr/bin/docker container inspect searx 2&gt; /dev/null || /usr/bin/docker run --name searx --rm -d -v /home/admin/searx:/etc/searx -p 8089:8080 -e BASE_URL=http://localhost:8089/ searx/searx"
ExecStart=/usr/bin/docker start -a searx
ExecStop=/usr/bin/docker stop -t 10 searx
[Install]
WantedBy=multi-user.target
</code></pre></div></div>
<p>Recharger les services</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl daemon-reload
</code></pre></div></div>
<p>Le fichier dunité crée un nouveau service et associe les commandes de démarrage et darrêt du docker aux séquences de démarrage et darrêt du service.</p>
<p>Le fichier unit décrit comme des dépendances la cible réseau en ligne et la prise docker, si la prise docker ne démarre pas ce service ne le fera pas non plus. Il ajoute également une dépendance à docker.service, de sorte que ce service ne fonctionnera pas tant que docker.service naura pas démarré.</p>
<p>Nous pouvons maintenant démarrer/arrêter le service en émettant la commande correspondante :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start searx # sudo systemctl stop searx
</code></pre></div></div>
<p>Vérifier localement</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl --location --verbose --head --insecure localhost:8089
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[...]
* Trying 127.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x5614e62aef90)
* Connected to localhost (127.0.0.1) port 8089 (#0)
&gt; HEAD / HTTP/1.1
&gt; Host: localhost:8089
&gt; User-Agent: curl/7.64.0
&gt; Accept: */*
&gt;
&lt; HTTP/1.1 200 OK
HTTP/1.1 200 OK
[...]
</code></pre></div></div>
<p>Modifier le fichier de configuration</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano ${PWD}/searx/settings.yml
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>general:
instance_name : "yann-searx" # displayed name
server:
base_url : http://localhost:8089/ # Set custom base_url. Possible values: False or "https://your.custom.host/lo
cation/"
ui:
theme_args :
oscar_style : logicodev-dark # default style of oscar
results_on_new_tab: True # Open result links in a new tab by default
# supprimer la ligne 'disabled : True' des éléments ci dessous
- name : ddg definitions
engine : duckduckgo_definitions
shortcut : ddd
weight : 2
- name : duckduckgo
engine : duckduckgo
shortcut : ddg
- name : duckduckgo images
engine : duckduckgo_images
shortcut : ddi
timeout: 3.0
</code></pre></div></div>
<p>Redémarrage pour prise en charge des modifications</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart searx
</code></pre></div></div>
<p>Valider le service pour quil fonctionne au démarrage en courant :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable searx
</code></pre></div></div>
<p>Pour info, docker ID</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker ps
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dfefa57f88f9 searx/searx "/sbin/tini -- /usr/…" 9 minutes ago Up 9 minutes 0.0.0.0:8089-&gt;8080/tcp searx
</code></pre></div></div>
<p>Redémarrer le container par son ID : <code class="language-plaintext highlighter-rouge">docker restart dfefa57f88f9</code></p>
<p><strong>TEST à partir dun poste distant</strong> <br />
Exécuter sur un poste distant</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -L 9000:localhost:8089 cxuser@135.181.27.140 -p 55140 -i /home/yannick/.ssh/cx11_ed25519
</code></pre></div></div>
<p>Sur le même poste , ouvrir le navigateur avec un lien <a href="http://localhost:9000">http://localhost:9000</a></p>
<p><img src="/images/cx11-docker-searx.png" alt="Texte alternatif" width="600" /></p>
<p><strong>Proxy searx</strong><br />
Installer application yunohost proxy <strong>redirect</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app install https://github.com/YunoHost-Apps/redirect_ynh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Choose a domain for your redirect (default: cinay.eu): searx.yanfi.space
Choose a path for your redirect (default: /redirect): /
Redirect destination path (default: http://127.0.0.1): http://127.0.0.1:8089
Redirect type [public_302 | public_301 | public_proxy | private_proxy] (default: public_302): public_proxy
Info: Installing redirect...
[...]
Success! Installation completed
</code></pre></div></div>
<p>Modifier létiquette <code class="language-plaintext highlighter-rouge">redirect</code> (searx.cinay.eu)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app change-label redirect 'Moteur Recherche searx.cinay.eu'
</code></pre></div></div>
<p>Accès lien https://searx.yanfi.space</p>
<p><strong>Mise à jour de limage docker searx</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /home/admin
</code></pre></div></div>
<p>Télécharge la dernière image searx</p>
<table>
<tbody>
<tr>
<td>docker images format “{{.Repository}}:{{.Tag}}”</td>
<td>grep :latest</td>
<td>xargs -L1 docker pull;</td>
</tr>
</tbody>
</table>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>latest: Pulling from searx/searx
339de151aab4: Pull <span class="nb">complete
</span>cb464254eb0a: Pull <span class="nb">complete
</span>3df700c30092: Pull <span class="nb">complete
</span>9a4946c2a738: Pull <span class="nb">complete
</span>2c615ec6f7fa: Pull <span class="nb">complete
</span>ef48a2d171a2: Pull <span class="nb">complete
</span>Digest: sha256:b4df2141a868644563f82680d66dc0d3c1d366f598ffc1cdb484d796c117230f
Status: Downloaded newer image <span class="k">for </span>searx/searx:latest
</code></pre></div></div>
<p>Liste des images</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker images
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>REPOSITORY TAG IMAGE ID CREATED SIZE
searx/searx latest 2b9a1d1fc86a 5 days ago 205MB
searx/searx &lt;none&gt; 096886989dad 7 months ago 161MB
</code></pre></div></div>
<p>Arrêt image searx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl stop searx.service
</code></pre></div></div>
<p>Supprimer limage par ID</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker rmi 096886989dad
</code></pre></div></div>
<p>Les images restantes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker images
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>REPOSITORY TAG IMAGE ID CREATED SIZE
searx/searx latest 2b9a1d1fc86a 5 days ago 205MB
</code></pre></div></div>
<p>Relancer le service</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start searx.service
sudo systemctl status searx.service
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>● searx.service - searx container
Loaded: loaded <span class="o">(</span>/etc/systemd/system/searx.service<span class="p">;</span> enabled<span class="p">;</span> vendor preset: enabled<span class="o">)</span>
Active: active <span class="o">(</span>running<span class="o">)</span> since Fri 2021-08-20 18:26:17 CEST<span class="p">;</span> 17s ago
Process: 15680 <span class="nv">ExecStartPre</span><span class="o">=</span>/bin/bash <span class="nt">-c</span> /usr/bin/docker container inspect searx 2&gt; /dev/null <span class="o">||</span> /usr/bin/docker run <span class="nt">--name</span> sear
Main PID: 15788 <span class="o">(</span>docker<span class="o">)</span>
Tasks: 7 <span class="o">(</span>limit: 4579<span class="o">)</span>
Memory: 21.5M
CGroup: /system.slice/searx.service
└─15788 /usr/bin/docker start <span class="nt">-a</span> searx
Aug 20 18:26:16 yanfi.space systemd[1]: Starting searx container...
Aug 20 18:26:16 yanfi.space bash[15680]: <span class="o">[]</span>
Aug 20 18:26:16 yanfi.space bash[15680]: 6a7551c7a9fbbdc86e234aa07dbadde13ecd2878cef7beea49272b9de2a0b313
Aug 20 18:26:17 yanfi.space systemd[1]: Started searx container.
Aug 20 18:26:17 yanfi.space docker[15788]: searx version 1.0.0-200-313a9847
Aug 20 18:26:17 yanfi.space docker[15788]: Use existing /etc/searx/uwsgi.ini
Aug 20 18:26:17 yanfi.space docker[15788]: Use existing /etc/searx/settings.yml
Aug 20 18:26:17 yanfi.space docker[15788]: Listen on 0.0.0.0:8080
Aug 20 18:26:17 yanfi.space docker[15788]: <span class="o">[</span>uWSGI] getting INI configuration from /etc/searx/uwsgi.ini
Aug 20 18:26:17 yanfi.space docker[15788]: <span class="o">[</span>uwsgi-static] added mapping <span class="k">for</span> /static <span class="o">=&gt;</span> /usr/local/searx/searx/static
</code></pre></div></div>
<h3 id="navidrome-stream-audio">Navidrome (stream audio)</h3>
<p><em>Navidrome est un serveur et un streamer de collection de musique en ligne open source. Il vous donne la liberté découter votre playlist à partir de nimporte quel navigateur ou appareil mobile.</em></p>
<p>Votre musique est a stockée par default dans le dossier multimédia partagé /home/yunohost.multimedia/share/Music. Ce dossier, facilement accessible depuis Nextcloud avec Stockages externes activée, vous permettra duploader facilement vos fichiers de musique sur votre server.</p>
<p>Vous pouvez personnaliser le dossier de stockage de vos fichiers de musique en éditant le fichier de configuration <strong>/var/lib/navidrome/navidrome.toml</strong> et rediriger la variable <code class="language-plaintext highlighter-rouge">MusicFolder = "/home/yunohost.multimedia/share/Music"</code>. Vous pouvez également changer dautre réglage en vous aidant de la <a href="https://www.navidrome.org/docs/usage/configuration-options/">documentation</a>.</p>
<p>En mode su</p>
<p>Ajout domaine et certificats zic.yanfi.space</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add zic.yanfi.space
yunohost domain cert-install zic.yanfi.space --no-checks
</code></pre></div></div>
<p>Installer navidrome</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/navidrome_ynh/tree/testing --debug
</code></pre></div></div>
<p>domaine : zic.yanfi.space<br />
racine : /<br />
anonyme : oui</p>
<p>Modification fichier de configuration, dossier musique et scan</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /var/lib/navidrome/navidrome.toml
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Folder where your music library is stored. Can be read-only
MusicFolder = "/opt/sshfs/musique"
# How frequently to scan for changes in your music library. Set it to 0 to disable scans
ScanSchedule = '@every 24h'
</code></pre></div></div>
<p>Redémarrer le service</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart navidrome.service
</code></pre></div></div>
<p>Modifier létiquette <code class="language-plaintext highlighter-rouge">navidrome</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label navidrome 'Zic Navidrome zic.cinay.eu'
</code></pre></div></div>
<h3 id="rainloop">Rainloop</h3>
<p><img src="/images/rainloop1.png" alt="" width="150" /></p>
<p>En mode su</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install rainloop
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Choose the domain where this app should be installed [cinay.eu | gitea.cinay.eu | static.cinay.eu | yanfi.net | yanfi.space | searx.yanfi.space | zic.yanfi.space] (default: yanfi.space):
Choose the path where this app should be installed (default: /rainloop):
Should this app be exposed to anonymous visitors? [yes | no] (default: no):
Choose an administration password for this app:
Do you want to add YunoHost users to the recipients suggestions? [yes | no] (default: yes):
Select default language [de | en | es | fr | it | pt] (default: en): fr
[...]
Info: [####################] &gt; Installation of rainloop completed
Success! Installation completed
</code></pre></div></div>
<h3 id="librespeed">LibreSpeed</h3>
<p><img src="/images/icon_huge.png" alt="LibreSpeed" width="50" /></p>
<p><em>Test de vitesse de connexion très léger.<a href="https://fdossena.com/?p=speedtest/index.frag">LibreSpeed</a></em></p>
<p>domaine : yanfi.space<br />
site : /librespeed</p>
<p>En mode su</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install librespeed # un mot de passe administartion est demandé
</code></pre></div></div>
<p>Le fichier de configuration nginx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/nginx/conf.d/yanfi.space.d/librespeed.conf
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> rewrite ^/librespeed$ /librespeed/ permanent;
location /librespeed/ {
# Path to source
alias /var/www/librespeed/ ;
# Force usage of https
if ($scheme = http) {
rewrite ^ https://$server_name$request_uri? permanent;
}
### Example PHP configuration (remove it if not used)
index yann-singleServer-full.html index.php;
# Common parameter to increase upload size limit in conjunction with dedicated php-fpm file
client_max_body_size 256M;
try_files $uri $uri/ /index.php;
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_pass unix:/var/run/php/php7.3-fpm-librespeed.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param REMOTE_USER $remote_user;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
### End of PHP configuration part
# Include SSOWAT user panel.
include conf.d/yunohost_panel.conf.inc;
}
</code></pre></div></div>
<p class="info">Le fichier original <code class="language-plaintext highlighter-rouge">example-singleServer-full.html</code> a été remplacé par <code class="language-plaintext highlighter-rouge">yann-singleServer-full.html</code></p>
<p>https://yanfi.space/librespeed</p>
<h3 id="calibre-ebookyanfispace">Calibre ebook.yanfi.space</h3>
<p>Source : https://github.com/janeczku/calibre-web<br />
Caractéristiques</p>
<ul>
<li>Interface HTML5 Bootstrap 3</li>
<li>configuration graphique complète</li>
<li>Gestion des utilisateurs avec des permissions par utilisateur à grain fin</li>
<li>Interface administrateur</li>
<li>Interface utilisateur en brésilien, tchèque, néerlandais, anglais, finnois, français, allemand, grec, hongrois, italien, japonais, khmer, polonais, russe, chinois simplifié, espagnol, suédois, turc, ukrainien.</li>
<li>Flux OPDS pour les applications de lecture de livres électroniques</li>
<li>Filtrez et recherchez par titres, auteurs, tags, séries et langues.</li>
<li>Créer une collection de livres personnalisée (étagères)</li>
<li>Prise en charge de lédition des métadonnées des livres électroniques et de la suppression des livres électroniques de la bibliothèque Calibre.</li>
<li>Prise en charge de la conversion des eBooks par les binaires Calibre</li>
<li>Restriction du téléchargement des livres électroniques aux utilisateurs connectés</li>
<li>Support pour lenregistrement public des utilisateurs</li>
<li>Envoi deBooks vers des appareils Kindle dun simple clic de souris</li>
<li>Synchronisation de vos appareils Kobo avec votre bibliothèque Calibre via Calibre-Web</li>
<li>Prise en charge de la lecture des eBooks directement dans le navigateur (.txt, .epub, .pdf, .cbr, .cbt, .cbz, .djvu)</li>
<li>Téléchargement de nouveaux livres dans de nombreux formats, y compris les formats audio (.mp3, .m4a, .m4b)</li>
<li>Prise en charge des colonnes personnalisées de Calibre</li>
<li>Possibilité de masquer le contenu en fonction des catégories et du contenu des colonnes personnalisées par utilisateur.</li>
<li>Possibilité de mise à jour automatique</li>
<li>Connexion “Magic Link” pour faciliter la connexion aux eReaders</li>
<li>Connexion via LDAP, google/github oauth et via lauthentification proxy.</li>
</ul>
<p>Ajout domaine et certificats ebook.yanfi.space</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add ebook.yanfi.space
yunohost domain cert-install ebook.yanfi.space --no-checks
</code></pre></div></div>
<p>Installer lapplication <strong>Calibre-web</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/calibreweb_ynh
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Choose the domain where this app should be installed [cinay.eu | gitea.cinay.eu | map.cinay.eu | static.cinay.eu | yanfi.net | yanfi.space | ebook.yanfi.space | searx.yanfi.space | zic.yanfi.space] (default: yanfi.space): ebook.yanfi.space
Choose the path where this app should be installed (default: /calibre): /
Choose an administrator user for this app [yann | claudine | yanfi]: yann
Should this app be exposed to anonymous visitors? [yes | no] (default: no): yes
Select a default language [fr | en | es | de] (default: fr):
Do you want to allow uploading of books? [yes | no] (default: no):
Do you want to allow access to the library to all Yunohost users? [yes | no] (default: yes):
</code></pre></div></div>
<p><strong>Le dossier des livres</strong> est une copie dun dossier distant qui est mis à jour une fois par jour<br />
Synchronisation du dossier local <code class="language-plaintext highlighter-rouge">/home/yunohost.multimedia/share/eBook/</code> avec le dossier distant <code class="language-plaintext highlighter-rouge">/home/usernl/backup/BiblioCalibre</code> du serveur xoyaz.xyz<br />
Lopération est exécutable en mode su seulement</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rsync -avz --delete --rsync-path="sudo rsync" -e "ssh -p 55051 -i /home/admin/.ssh/hms-sto-250 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" userhms@hms.xoyaz.xyz:/home/userhms/sshfs/BiblioCalibre/* /home/yunohost.multimedia/share/eBook/ &amp;&amp; chown calibreweb.calibreweb -R /home/yunohost.multimedia/share/eBook/
Créer une tâche crontab
sudo crontab -e
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Synchronisation du dossier local /home/yunohost.multimedia/share/eBook/ avec le dossier distant /home/userhms/sshfs/BiblioCalibre du serveur hms.xoyaz.xyz
# Tous les jours à 4h00 du matin
0 4 * * * rsync -avz --delete --rsync-path="sudo rsync" -e "ssh -p 55051 -i /home/admin/.ssh/hms-sto-250 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" userhms@hms.xoyaz.xyz:/home/userhms/sshfs/BiblioCalibre/* /home/yunohost.multimedia/share/eBook/ &amp;&amp; chown calibreweb.calibreweb -R /home/yunohost.multimedia/share/eBook/
</code></pre></div></div>
<p class="info">A FAIRE : En cas de modification du dossier /home/userhms/sshfs/BiblioCalibre sur le serveur hms.xoyaz.xyz<br />
Il faut effectuer une synchro du dossier par rsync depuis le serveur hms.xoyaz.xyz vers yanfi.space</p>
<p><strong>Les traductions de lapplication “calibreweb_ynh”</strong></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>find /var/www/calibreweb/cps/templates/ <span class="nt">-name</span> <span class="s2">"*.*"</span> <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s#'Sort according to book date, newest first'#'Trier selon la date du livre, le plus récent en premier'#g"</span> <span class="o">{}</span> <span class="se">\;</span>
find /var/www/calibreweb/cps/templates/ <span class="nt">-name</span> <span class="s2">"*.*"</span> <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s#'Sort according to book date, oldest first'#'Trier selon la date du livre, le plus ancien en premier'#g"</span> <span class="o">{}</span> <span class="se">\;</span>
find /var/www/calibreweb/cps/templates/ <span class="nt">-name</span> <span class="s2">"*.*"</span> <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s#'Sort title in alphabetical order'#'Trier le titre par ordre alphabétique'#g"</span> <span class="o">{}</span> <span class="se">\;</span>
find /var/www/calibreweb/cps/templates/ <span class="nt">-name</span> <span class="s2">"*.*"</span> <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s#'Sort title in reverse alphabetical order'#'Trier le titre en ordre alphabétique inverse'#g"</span> <span class="o">{}</span> <span class="se">\;</span>
find /var/www/calibreweb/cps/templates/ <span class="nt">-name</span> <span class="s2">"*.*"</span> <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s#'Sort authors in alphabetical order'#'Trier les auteurs par ordre alphabétique'#g"</span> <span class="o">{}</span> <span class="se">\;</span>
find /var/www/calibreweb/cps/templates/ <span class="nt">-name</span> <span class="s2">"*.*"</span> <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s#'Sort authors in reverse alphabetical order'#'Trier les auteurs par ordre alphabétique inverse'#g"</span> <span class="o">{}</span> <span class="se">\;</span>
find /var/www/calibreweb/cps/templates/ <span class="nt">-name</span> <span class="s2">"*.*"</span> <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s#'Sort according to publishing date, newest first'#'Trier selon la date de publication, les plus récentes en premier'#g"</span> <span class="o">{}</span> <span class="se">\;</span>
find /var/www/calibreweb/cps/templates/ <span class="nt">-name</span> <span class="s2">"*.*"</span> <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s#'Sort according to publishing date, oldest first'#'Trier selon la date de publication, la plus ancienne en premier'#g"</span> <span class="o">{}</span> <span class="se">\;</span>
</code></pre></div></div>
<p>Les fichiers de traduction française dans le dossier <code class="language-plaintext highlighter-rouge">/var/www/calibreweb/cps/translations/fr/LC_MESSAGES/</code><br />
Editer et modifier le fichier <code class="language-plaintext highlighter-rouge">messages.po</code><br />
Convertir le <code class="language-plaintext highlighter-rouge">po</code> vers <code class="language-plaintext highlighter-rouge">mo</code> , lien <a href="http://po2mo.net/">http://po2mo.net/</a><br />
Redémarrer le service <code class="language-plaintext highlighter-rouge">calibreweb</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart calibreweb
</code></pre></div></div>
<p>Ouverture du lien https://ebook.yanfi.space<br />
<img src="/images/calibre-web3.png" alt="" width="400" /> <img src="/images/calibre-web4.png" alt="" width="400" /></p>
<p><img src="/images/calibre-web5.png" alt="" width="400" /> <img src="/images/calibre-web7.png" alt="" width="400" /></p>
<p><img src="/images/calibre-web6.png" alt="" width="400" /> <img src="/images/calibre-web8.png" alt="" width="400" /></p>
<p><img src="/images/calibre-web9.png" alt="" width="400" /></p>
<h2 id="sauvegardes">Sauvegardes</h2>
<h3 id="borgbackup">BorgBackup</h3>
<ul>
<li><a href="/2021/09/25/BorgBackup-Client-Serveur.html">BorgBackup client serveur</a></li>
</ul>
<h3 id="via-rsync">Via rsync</h3>
<p class="warning">Sauvegarde complète de yunohost <strong>yanfi.space</strong> sur le serveur <strong>hms.xoyaz.xyz</strong> via <strong>rsync</strong><br />
est désactivée depuis la mise en place de la sauvegarde par <strong>BorgBackup</strong></p>
<p>Créer le bash <code class="language-plaintext highlighter-rouge">~/backup-hms.xoyaz.xyz.sh</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano ~/backup-hms.xoyaz.xyz.sh
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/sh</span>
<span class="c"># Créer une sauvegarde totale localement</span>
yunohost backup create <span class="nt">--debug</span>
<span class="c"># Copier cette sauvegarde sur le distant hms.xoyaz.xyz</span>
rsync <span class="nt">-avz</span> <span class="nt">--progress</span> <span class="nt">--stats</span> <span class="nt">--human-readable</span> <span class="nt">--rsync-path</span><span class="o">=</span><span class="s2">"sudo rsync"</span> <span class="nt">-e</span> <span class="s2">"ssh -p 55051 -i /home/admin/.ssh/hms-sto-250 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"</span> /home/yunohost.backup/archives/<span class="si">$(</span><span class="nb">date</span> <span class="s1">'+%Y%m%d'</span><span class="si">)</span><span class="k">*</span> userhms@hms.xoyaz.xyz:/home/userhms/sshfs/yanfi.space/ <span class="p">;</span> <span class="se">\</span>
<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> <span class="nt">-eq</span> 0 <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="se">\</span>
<span class="nb">echo</span> <span class="s2">"Sauvegardes </span><span class="si">$(</span><span class="nb">date</span> <span class="s1">'+%Y%m%d'</span><span class="si">)</span><span class="s2">* -&gt; OK"</span> | systemd-cat <span class="nt">-t</span> allsync <span class="nt">-p</span> info <span class="p">;</span> <span class="se">\</span>
<span class="nb">rm</span> /home/yunohost.backup/archives/<span class="si">$(</span><span class="nb">date</span> <span class="s1">'+%Y%m%d'</span><span class="si">)</span><span class="k">*</span> <span class="p">;</span> <span class="se">\</span>
<span class="k">else</span> <span class="se">\</span>
<span class="nb">echo</span> <span class="s2">"Sauvegardes </span><span class="si">$(</span><span class="nb">date</span> <span class="s1">'+%Y%m%d'</span><span class="si">)</span><span class="s2">* -&gt; ERREUR"</span> | systemd-cat <span class="nt">-t</span> allsync <span class="nt">-p</span> emerg <span class="p">;</span> <span class="se">\</span>
<span class="k">fi</span>
</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 ~/backup-hms.xoyaz.xyz.sh
</code></pre></div></div>
<p>Le résultat de la commande est dans le journal</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>journalctl --no-pager -t allsync --since today
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-- Logs begin at Wed 2021-09-15 11:48:08 CEST, end at Wed 2021-09-15 18:47:50 CEST. --
Sep 15 18:24:45 yanfi.space allsync[16720]: Sauvegardes 20210915* -&gt; OK
</code></pre></div></div>
<p>Tâche</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo crontab -e
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>10 02 * * * /home/admin/backup-hms.xoyaz.xyz.sh &gt; /dev/null
</code></pre></div></div>
<h2 id="yunohost-">Yunohost +</h2>
<h3 id="maintenance">Maintenance</h3>
<p><strong>sauvegardes borg sur le serveur xoyaz.yz</strong><br />
Clé SSH pour lister les sauvegardes borg sur le serveur xoyaz.yz</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t ed25519 -f ~/.ssh/borg_yanfi
</code></pre></div></div>
<p>Se connecter au serveur xoyaz.xyz et ajouter la clé publique</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh userhms@45.145.166.51 -p 55051 -i /home/yann/.ssh/hms-sto-250
sudo -u borgbackup -s # utilisateur borgbackup
echo 'ssh-ed25519 AAAAkjhreszFJE5AAAAIBWaYu5BvBcpuTeP4/0QXLm3/vmKP7EagcWXi+MGygJ7 yann@archyan' &gt;&gt; /home/backup/.ssh/authorized_keys
</code></pre></div></div>
<p>Test connexion SSH</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh borgbackup@xoyaz.xyz -p 55051 -i /home/yann/.ssh/borg_yanfi
</code></pre></div></div>
<h3 id="erreurs-et-avertissements">Erreurs et avertissements</h3>
<p>yanfi.space<br />
Mise à jour reverse DNS IPV4 IPV6<br />
45.145.166.178 → yanfi.space<br />
2a04:ecc0:8:a8:4567:4989::1 → yanfi.space</p>
<p>Mise à jour yunohost 02/02/2021</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost diagnosis run --force
</code></pre></div></div>
<p>Le détail</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost diagnosis show --issues
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>reports:
0:
description: Base system
id: basesystem
items:
status: WARNING
summary: It looks like apt (the package manager) is configured to use the backports repository. Unless you really know what you are doing, we strongly discourage from installing packages from backports, because it's likely to create unstabilities or conflicts on your system.
1:
description: Email
id: mail
items:
0:
details:
- The blacklist reason is: "http://www.barracudanetworks.com/reputation/?pr=1&amp;ip=45.145.166.178"
- After identifying why you are listed and fixed it, feel free to ask for your IP or domaine to be removed on https://barracudacentral.org/rbl/
status: ERROR
summary: Your IP or domain 45.145.166.178 is blacklisted on Barracuda Reputation Block List
1:
details:
- The blacklist reason is: "https://matrix.spfbl.net/2a01:4f9:c010:45b3:0:0:0:1"
- After identifying why you are listed and fixed it, feel free to ask for your IP or domaine to be removed on https://spfbl.net/en/dnsbl/
status: ERROR
summary: Your IP or domain 2a04:ecc0:8:a8:4567:4989::1 is blacklisted on SPFBL.net RBL
2:
description: System configurations
id: regenconf
items:
details: This is probably OK if you know what you're doing! YunoHost will stop updating this file automatically... But beware that YunoHost upgrades could contain important recommended changes. If you want to, you can inspect the differences with 'yunohost tools regen-conf ssh --dry-run --with-diff' and force the reset to the recommended configuration with 'yunohost tools regen-conf ssh --force'
status: WARNING
summary: Configuration file /etc/ssh/sshd_config appears to have been manually modified.
</code></pre></div></div>
<p>Email</p>
<p><strong>Résoudre le blocage barracuda</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> - The blacklist reason is: "http://www.barracudanetworks.com/reputation/?pr=1&amp;ip=45.145.166.178"
- After identifying why you are listed and fixed it, feel free to ask for your IP or domaine to be removed on https://barracudacentral.org/rbl/
status: ERROR
summary: Your IP or domain 45.145.166.178 is blacklisted on Barracuda Reputation Block List
</code></pre></div></div>
<p>Lien <a href="https://barracudacentral.org/rbl/removal-request">https://barracudacentral.org/rbl/removal-request</a> , il faut renseigner ladresse ip <code class="language-plaintext highlighter-rouge">45.145.166.178</code> et un mail <br />
Traduction du résultat:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Demande reçue
Merci d'avoir soumis votre demande. S'il s'agit de votre première demande, la réputation de votre adresse IP sera portée à "normale" pendant 48 heures, le temps que nous menions notre enquête. Il peut s'écouler jusqu'à une heure avant que la réputation ne se propage à tous les pare-feu antispam Barracuda dans le monde. Nous vous remercions de votre patience et vous prions de nous excuser pour tout désagrément.
Votre numéro de confirmation est BBR21612284433-86752-13901.
EmailReg.org
Une façon d'éviter que votre courrier électronique soit bloqué par inadvertance est d'enregistrer votre domaine et vos adresses IP sur EmailReg.org. Les courriels provenant de noms de domaine et d'adresses IP correctement enregistrés sur EmailReg.org peuvent être automatiquement exemptés des couches de défense du filtrage du spam sur les pare-feu antispam Barracuda et d'autres solutions antispam, ce qui permet d'éviter que votre courriel soit accidentellement bloqué.
</code></pre></div></div>
<p>Résoudre le blocage</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> - The blacklist reason is: "https://matrix.spfbl.net/2a01:4f9:c010:45b3:0:0:0:1"
- After identifying why you are listed and fixed it, feel free to ask for your IP or domaine to be removed on https://spfbl.net/en/dnsbl/
status: ERROR
summary: Your IP or domain 2a04:ecc0:8:a8:4567:4989::1 is blacklisted on SPFBL.net RBL
</code></pre></div></div>
<p>Vérifier rDNS</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[yann@archyan ~]$ dig ptr 127.222.216.95.in-addr.arpa +noall +answer
127.222.216.95.in-addr.arpa. 86400 IN PTR yanfi.space.
[yann@archyan ~]$ dig PTR 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.b.5.4.0.1.0.c.9.f.4.0.1.0.a.2.ip6.arpa +noall +answer
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.b.5.4.0.1.0.c.9.f.4.0.1.0.a.2.ip6.arpa. 86400 IN PTR yanfi.space.
</code></pre></div></div>
<h3 id="thème-yann">Thème “yann”</h3>
<p>A partir dun thème existant : <code class="language-plaintext highlighter-rouge">cp -r /usr/share/ssowat/portal/assets/themes/{light,yann}</code> <br />
Les images : <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/img/</code><br />
Image de fond : <code class="language-plaintext highlighter-rouge">iceland-aurore-polaire.jpg</code><br />
Logo : ym-70x70.png , yannick-white16x16.png <br />
Le fichier css : <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/themes/yann/custom_portal.css</code><br />
Modifier la balise <code class="language-plaintext highlighter-rouge">body {</code></p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">/*
===============================================================================
This file contain extra CSS rules to customize the YunoHost user portal and
can be used to customize app tiles, buttons, etc...
===============================================================================
*/</span>
<span class="nt">body</span> <span class="p">{</span>
<span class="nl">margin</span><span class="p">:</span><span class="m">0</span><span class="p">;</span>
<span class="nl">padding</span><span class="p">:</span><span class="m">0</span><span class="p">;</span>
<span class="nl">background</span><span class="p">:</span> <span class="sx">url("../../img/iceland-aurore-polaire.jpg")</span> <span class="nb">no-repeat</span> <span class="nb">center</span> <span class="nb">fixed</span><span class="p">;</span>
<span class="nl">-webkit-background-size</span><span class="p">:</span> <span class="n">cover</span><span class="p">;</span> <span class="c">/* pour anciens Chrome et Safari */</span>
<span class="nl">background-size</span><span class="p">:</span> <span class="n">cover</span><span class="p">;</span> <span class="c">/* version standardisée */</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Personnaliser le logo<br />
Modifier le fichier <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/themes/yann/custom_portal.css</code></p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">/* Logo */</span>
<span class="nc">.ynh-logo</span> <span class="p">{</span>
<span class="nl">opacity</span><span class="p">:</span> <span class="m">0.7</span><span class="p">;</span>
<span class="nl">margin-top</span><span class="p">:</span> <span class="m">6em</span><span class="p">;</span>
<span class="nl">width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span>
<span class="nl">height</span><span class="p">:</span> <span class="m">9em</span><span class="p">;</span>
<span class="nl">background-image</span><span class="p">:</span> <span class="sx">url("../../img/ym-70x70.png")</span><span class="p">;</span>
<span class="nl">background-repeat</span><span class="p">:</span> <span class="nb">no-repeat</span><span class="p">;</span>
<span class="nl">background-position</span><span class="p">:</span> <span class="nb">center</span> <span class="m">100%</span><span class="p">;</span>
<span class="nl">background-size</span><span class="p">:</span> <span class="n">contain</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.user-container</span><span class="nd">:before</span> <span class="p">{</span>
<span class="nl">content</span><span class="p">:</span> <span class="sx">url("../../img/yannick-white64x64.png")</span><span class="p">;</span>
<span class="nl">background</span><span class="p">:</span> <span class="m">#0000</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Modifier le fichier <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/themes/yann/custom_overlay.css</code></p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">#ynh-overlay-switch</span> <span class="p">{</span>
<span class="c">/* FIXME : idk if this is an issue or not to have /yunohost/sso hard-coded here */</span>
<span class="nl">background-image</span><span class="p">:</span> <span class="sx">url("/yunohost/sso/assets/img/ym-70x70.png")</span><span class="p">;</span>
<span class="nl">right</span><span class="p">:</span> <span class="m">60px</span><span class="p">;</span>
<span class="nl">border-color</span><span class="p">:</span> <span class="m">#7EA93D</span><span class="p">;</span>
<span class="nl">background-color</span><span class="p">:</span> <span class="m">#7EA93D</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Activer le thème <code class="language-plaintext highlighter-rouge">nano /etc/ssowat/conf.json.persistent</code></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"theme"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"yann"</span><span class="p">,</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>!!! Rrafraîchir le cache du navigateur pour que le thème se propage complètement ( Ctrl+Maj+R sur Firefox)</p>
<p><img src="/images/cx21-yunohost-theme-yann.png" alt="" width="600" /></p>
<h3 id="mise-à-jour">Mise à jour</h3>
<h4 id="system-et-app">system et app</h4>
<p>En mode su</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost tools update
# si mise à jour possible
yunohost tools upgrade apps
yunohost tools upgrade system
</code></pre></div></div>
<p>AIDE</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>YunoHost update
positional arguments:
TARGET What to update, "apps" (application catalog) or "system" (fetch
available package upgrades, equivalent to apt update), "all" for
both
optional arguments:
-h, --help show this help message and exit
--apps (Deprecated, see first positional arg) Fetch the application
list to check which apps can be upgraded
--system (Deprecated, see first positional arg) Fetch available system
packages upgrades (equivalent to apt update)
root@yanfi:/home/admin# yunohost tools upgrade -h
usage: yunohost tools upgrade [{apps,system}] [-h] [--apps] [--system]
YunoHost upgrade
positional arguments:
{apps,system} What to upgrade, either "apps" (all apps) or "system" (all
system packages)
optional arguments:
-h, --help show this help message and exit
--apps (Deprecated, see first positional arg) Upgrade all
applications
--system (Deprecated, see first positional arg) Upgrade only the
system packages
</code></pre></div></div>
<h4 id="navidrome">Navidrome</h4>
<p><strong>Mise à jour Navidrome avec une version compilée (langue FR par défaut)</strong></p>
<p>Mise à jour (version compilée avec langue française par défaut et transmise par filezilla)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl stop navidrome.service
sudo cp ~/navidrome /opt/yunohost/navidrome/navidrome
sudo chown -R navidrome:navidrome /opt/yunohost/navidrome
sudo chmod +x /opt/yunohost/navidrome
</code></pre></div></div>
<p>Relance et vérification</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart navidrome
sudo yunohost service log navidrome
</code></pre></div></div>
<p><strong>NE PAS FAIRE MAJ Navidrome</strong><br />
<em>Il faut renseigner le fichier manifest.json avec la version update pour ne pas faire la mise à jour !!!</em><br />
EXEMPLE : <code class="language-plaintext highlighter-rouge">yunohost tools update</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[...]
apps:
0:
current_version: 0.42.1~ynh1
id: navidrome
label: Zic Navidrome zic.cinay.eu
new_version: 0.42.1~ynh2
</code></pre></div></div>
<p>Modifier la version dans le fichier manifest.json de lapplication Navidrome</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sed -i 's/0.42.1~ynh1/0.42.1~ynh2/g' /etc/yunohost/apps/navidrome/manifest.json
</code></pre></div></div>
</div>
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2021-10-02T00:00:00+02: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="/2021/09/29/Archlinux_Debian-Compilation_go_Audio_Navidrome.html">Archlinux Debian - Compilation go Audio Navidrome</a></div><div class="next"><span>SUIVANT</span><a href="/2021/10/02/OVH-VPS-Starter-1cpu-2GoRam-20GoSSD-100Mbs.html">OVH VPS Starter</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>