3541 lines
290 KiB
HTML
3541 lines
290 KiB
HTML
|
<!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>Yunohost TIME4VPS debian 11 xoyaz.xyz - YannStatic</title>
|
|||
|
|
|||
|
<meta name="description" content="Installation yunohost beta stage (juin 2022) testing sur un serveur Debian 11 TIME4VPS">
|
|||
|
<link rel="canonical" href="https://static.rnmkcy.eu/2022/06/08/Time4Vps_serveur_debian_11.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} {title}</a></li>'
|
|||
|
searchResultTemplate: '<li><a href="{url}">{date} {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;">Yunohost TIME4VPS debian 11 xoyaz.xyz</h1></header></div><meta itemprop="headline" content="Yunohost TIME4VPS debian 11 xoyaz.xyz"><div class="article__info clearfix"><ul class="left-col menu"><li>
|
|||
|
<a class="button button--secondary button--pill button--sm"
|
|||
|
href="/archive.html?tag=vps">vps</a>
|
|||
|
</li><li>
|
|||
|
<a class="button button--secondary button--pill button--sm"
|
|||
|
href="/archive.html?tag=yunohost">yunohost</a>
|
|||
|
</li></ul><ul class="right-col menu"><li>
|
|||
|
<i class="far fa-calendar-alt"></i> <span title="Création" style="color:#FF00FF"> 8 juin 2022</span>
|
|||
|
|
|||
|
<span title="Modification" style="color:#00FF7F">12 sept. 2023</span></li></ul></div><meta itemprop="datePublished" content="2023-09-12T00:00:00+02:00">
|
|||
|
<meta itemprop="keywords" content="vps,yunohost"><div class="js-article-content">
|
|||
|
<div class="layout--article"><!-- start custom article top snippet -->
|
|||
|
<style>
|
|||
|
#myBtn {
|
|||
|
display: none;
|
|||
|
position: fixed;
|
|||
|
bottom: 10px;
|
|||
|
right: 10px;
|
|||
|
z-index: 99;
|
|||
|
font-size: 12px;
|
|||
|
font-weight: bold;
|
|||
|
border: none;
|
|||
|
outline: none;
|
|||
|
background-color: white;
|
|||
|
color: black;
|
|||
|
cursor: pointer;
|
|||
|
padding: 5px;
|
|||
|
border-radius: 4px;
|
|||
|
}
|
|||
|
|
|||
|
#myBtn:hover {
|
|||
|
background-color: #555;
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
<button onclick="topFunction()" id="myBtn" title="Haut de page">⇧</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><p><em>Installation yunohost beta stage (juin 2022) testing sur un serveur Debian 11 <a href="https://www.time4vps.com/">TIME4VPS</a></em></p>
|
|||
|
|
|||
|
<p><img src="/images/time4vps-logo.png" alt="TIME4VPS" /> <em>fournisseur d’hébergement Web en Lituanie <img src="/images/lt.png" alt="" /></em></p>
|
|||
|
|
|||
|
<p>Connexion sur l’hébergeur TIME4VPS (zone client) : <a href="https://billing.time4vps.com/clientarea/">https://billing.time4vps.com/clientarea/</a><br />
|
|||
|
<strong>Modifier hostname</strong> <br />
|
|||
|
Cliquer sur <strong>Change Hostname</strong> et saisir <strong>xoyaz.xyz</strong> pour valider le <strong>reverse DNS</strong></p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><strong>Product/Service</strong> Linux VPS - Linux 8</li>
|
|||
|
<li><strong>Label</strong> yann-time4vps</li>
|
|||
|
<li><strong>Hostname</strong> xoyaz.xyz</li>
|
|||
|
<li><strong>Node</strong> k24-b18-lt1</li>
|
|||
|
<li><strong>Specs</strong>
|
|||
|
<ul>
|
|||
|
<li><strong>OS</strong>: Debian 11 (64-bit)</li>
|
|||
|
<li><strong>Processor</strong>: 3 x 2.6 GHz</li>
|
|||
|
<li><strong>Memory</strong>: 8192 MB</li>
|
|||
|
<li><strong>Storage</strong>: 80 GB</li>
|
|||
|
<li><strong>Bandwidth</strong>: 100 Mbps (Monthly limit: 16 TB)</li>
|
|||
|
<li>Upgrade / Downgrade</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li>Components Upgrade</li>
|
|||
|
<li>Backups Order now</li>
|
|||
|
<li><strong>IP(s)</strong>
|
|||
|
<ul>
|
|||
|
<li><strong>IPv4</strong> 195.181.242.156 Main IP</li>
|
|||
|
<li><strong>IPv4</strong> 10.181.242.156 Local IP</li>
|
|||
|
<li><strong>IPv6</strong> 2a02:7b40:c3b5:f29c::1 (xoyaz.xyz)</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>On se connecte en root sur le VPS</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh root@195.181.242.156
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="yunohost-xoyazxyz">Yunohost xoyaz.xyz</h2>
|
|||
|
|
|||
|
<p><img src="/images/yunohost.png" alt=" " /></p>
|
|||
|
|
|||
|
<h3 id="installation-et-configuration">Installation et configuration</h3>
|
|||
|
|
|||
|
<h4 id="installer-yunohost">Installer yunohost</h4>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><a href="https://forum.yunohost.org/t/beta-stage-testing-for-yunohost-11-0-bullseye-and-buster-bullseye-migration/18531">Beta-stage testing for Yunohost 11.0/Bullseye and Buster->Bullseye migration </a></li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Installation d’un nouveau YunoHost sur un Debian 11/Bullseye</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://install.yunohost.org/bullseye -O install_script
|
|||
|
bash install_script -d testing
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Patienter …</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
|
|||
|
┌───────────────────────────┤ SSH Configuration ├────────────────────────────┐
|
|||
|
│ │
|
|||
|
│ To improve the security of your server, it is recommended to let YunoHost │
|
|||
|
│ manage the SSH configuration. │
|
|||
|
│ Your current SSH configuration differs from the recommended configuration. │
|
|||
|
│ If you let YunoHost reconfigure it, the way you connect to your server │
|
|||
|
│ through SSH will change in the following way: │
|
|||
|
│ - you will not be able to connect as root through SSH. Instead you should │
|
|||
|
│ use the admin user ; │
|
|||
|
│ │
|
|||
|
│ Do you agree to let YunoHost apply those changes to your configuration and │
|
|||
|
│ therefore affect the way you connect through SSH ? │
|
|||
|
│ │
|
|||
|
│ <Yes> <No> │
|
|||
|
│ │
|
|||
|
└────────────────────────────────────────────────────────────────────────────┘
|
|||
|
Choix Yes
|
|||
|
|
|||
|
===============================================================================
|
|||
|
You should now proceed with Yunohost post-installation. This is where you will
|
|||
|
be asked for :
|
|||
|
- the main domain of your server ;
|
|||
|
- the administration password.
|
|||
|
|
|||
|
You can perform this step :
|
|||
|
- from the command line, by running 'yunohost tools postinstall' as root
|
|||
|
- or from your web browser, by accessing :
|
|||
|
- https://195.181.242.156/ (global IP, if you'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
|
|||
|
'Finalizing your setup' and 'Getting to know YunoHost'. It is available at
|
|||
|
the following URL : https://yunohost.org/admindoc
|
|||
|
===============================================================================
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="post-installation">Post-installation</h4>
|
|||
|
|
|||
|
<p class="info">Vous devez faire la post-installation pour configurer l’application Borg.</p>
|
|||
|
|
|||
|
<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: xoyaz.xyz
|
|||
|
New administration password: ****************
|
|||
|
Confirm new administration password: ****************
|
|||
|
Info: Installing YunoHost...
|
|||
|
Success! Self-signed certificate now installed for the domain 'xoyaz.xyz'
|
|||
|
Success! Domain created
|
|||
|
Success! The main domain has been changed
|
|||
|
Info: Your root password have been replaced by your admin password.
|
|||
|
Success! The administration password was changed
|
|||
|
Success! Firewall reloaded
|
|||
|
Success! App catalog system initialized!
|
|||
|
Info: Updating application catalog...
|
|||
|
Success! The application catalog has been updated!
|
|||
|
Success! The service 'yunohost-firewall' will now be automatically started during system boots.
|
|||
|
Success! Service 'yunohost-firewall' started
|
|||
|
Success! Configuration updated for 'ssh'
|
|||
|
[...]
|
|||
|
Warning: /usr/sbin/run-parts: line 5: fe80::200:c3ff:feb5:f29c%ens3 2a02:7b40:c3b5:f29c::1 10181242156 195181242156: syntax error in expression (error token is "::200:c3ff:feb5:f29c%ens3 2a02:7b40:c3b5:f29c::1 10181242156 195181242156")
|
|||
|
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 <username>' 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 l’admin yunohost</p>
|
|||
|
</blockquote>
|
|||
|
|
|||
|
<p>Motd</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rm /etc/motd && nano /etc/motd
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> __ __ _ _
|
|||
|
<span class="se">\ \ </span>/ /_ _ _ _ ___ | |_ ___ ___| |_
|
|||
|
<span class="se">\ </span>V /| <span class="o">||</span> <span class="o">||</span> <span class="s1">' \ / _ \| '</span> <span class="se">\ </span>/ _ <span class="se">\(</span>_-<| _|
|
|||
|
|_| <span class="se">\_</span>,_||_||_|<span class="se">\_</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="o">||</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="se">\/</span> _ <span class="se">\</span>
|
|||
|
|_| /_/ |___/<span class="o">(</span>_<span class="o">)</span>|_|<span class="se">\_</span>__/|_|<span class="o">(</span>_<span class="o">)</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="sb">`</span> <span class="o">||</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="se">\_\ \_</span>, |/__|
|
|||
|
|__/ |__/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="créer-utilisateur-yann">Créer utilisateur yann</h4>
|
|||
|
|
|||
|
<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: m
|
|||
|
Password: ************
|
|||
|
Confirm password: ************
|
|||
|
Available domains:
|
|||
|
- xoyaz.xyz
|
|||
|
Domain to use for the user's email address and XMPP account (default: xoyaz.xyz):
|
|||
|
Success! User created
|
|||
|
fullname: yann m
|
|||
|
mail: yann@xoyaz.xyz
|
|||
|
username: yann
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ajouter le droit de connexion ssh à un utilisateur (FACULTATIF)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost user permission add ssh yann
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>additional_urls:
|
|||
|
allowed: yann
|
|||
|
auth_header: False
|
|||
|
corresponding_users: yann
|
|||
|
label: SSH
|
|||
|
protected: True
|
|||
|
show_tile: False
|
|||
|
url: None
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="domaines-et-dns-ovh">Domaines et DNS OVH</h4>
|
|||
|
|
|||
|
<p><img src="/images/dns-logo.png" alt="" width="50" /></p>
|
|||
|
|
|||
|
<p>Configuration DNS domaine par défaut <strong>xoyaz.xyz</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain dns-conf xoyaz.xyz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; Basic ipv4/ipv6 records
|
|||
|
@ 3600 IN A 195.181.242.156
|
|||
|
@ 3600 IN AAAA 2a02:7b40:c3b5:f29c::1
|
|||
|
|
|||
|
; Mail
|
|||
|
@ 3600 IN MX 10 xoyaz.xyz.
|
|||
|
@ 3600 IN TXT "v=spf1 a mx -all"
|
|||
|
mail._domainkey 3600 IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZglyGftXQzOMoUKTeG3eWIvzkBwML2GDjDLJLZwHwncvS1/AnPSjqkB8htjUb9tvladfwDs+Rz2hb5HGzHhRDUWRyo6QE1yonzcQux6VDHYRBaF1jBFT18nTOK40mjTOb7pHhUJ/71XXMl9eOpVhzzLuWmEGs/6dURkJxOhLY0wIDAQAB"
|
|||
|
_dmarc 3600 IN TXT "v=DMARC1; p=none"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
; XMPP
|
|||
|
_xmpp-client._tcp 3600 IN SRV 0 5 5222 xoyaz.xyz.
|
|||
|
_xmpp-server._tcp 3600 IN SRV 0 5 5269 xoyaz.xyz.
|
|||
|
muc 3600 IN CNAME @
|
|||
|
pubsub 3600 IN CNAME @
|
|||
|
vjud 3600 IN CNAME @
|
|||
|
xmpp-upload 3600 IN CNAME @
|
|||
|
|
|||
|
; Extra
|
|||
|
* 3600 IN A 195.181.242.156
|
|||
|
* 3600 IN AAAA 2a02:7b40:c3b5:f29c::1
|
|||
|
@ 3600 IN CAA 128 issue "letsencrypt.org"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><img src="/images/ovh-logo-a.png" alt="" /><br />
|
|||
|
Se connecter à l’espace client du site OVH : <strong>Web cloud → Domaines → xoyaz.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 qu’il 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>
|
|||
|
|
|||
|
<h4 id="activer-certificats-ssl-lets-encrypt">Activer Certificats SSL Let’s Encrypt</h4>
|
|||
|
|
|||
|
<p><img src="/images/LetsEncrypt-a.png" alt="" /><br />
|
|||
|
On active les certificats SSL pour le domaine xoyaz.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain cert-install xoyaz.xyz --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Résultat</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[...]
|
|||
|
Success! Configuration updated for 'nginx'
|
|||
|
Success! Let's Encrypt certificate now installed for the domain 'xoyaz.xyz'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="proxy-headers-nginx">proxy headers nginx</h4>
|
|||
|
|
|||
|
<p>Pour éviter l’avertissement <code class="language-plaintext highlighter-rouge">[warn] could not build optimal proxy_headers_hash error</code>, on ajoute 2 lignes au nouveau fichier de configuration <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/proxy.conf</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>proxy_headers_hash_max_size 512;
|
|||
|
proxy_headers_hash_bucket_size 128;
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Recharger nginx : <code class="language-plaintext highlighter-rouge">sudo systemctl reload nginx</code></p>
|
|||
|
|
|||
|
<h4 id="thème-yann">Thème “yann”</h4>
|
|||
|
|
|||
|
<p>A partir d’un thème existant : <code class="language-plaintext highlighter-rouge">cp -r /usr/share/ssowat/portal/assets/themes/{unsplash,yako}</code> <br />
|
|||
|
Les images : <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/img/</code></p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>Image de fond : <code class="language-plaintext highlighter-rouge">code_coding_binary1920x1080.jpg</code></li>
|
|||
|
<li>Image logo : lettre-y-70x85.png</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Changer le “branding” du portail utilisateur “YunoHost” par “yann” (yann.png)<br />
|
|||
|
Copier yann.png dans le dossier <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/themes/yako/</code></p>
|
|||
|
|
|||
|
<p>Modifier le fichier css : <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/themes/yako/custom_portal.css</code></p>
|
|||
|
|
|||
|
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">/*Image de fond*/</span>
|
|||
|
<span class="nc">.ynh-user-portal</span> <span class="p">{</span>
|
|||
|
<span class="nl">background-image</span><span class="p">:</span> <span class="sx">url('../../img/code_coding_binary1920x1080.jpg')</span> <span class="cp">!important</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-size</span><span class="p">:</span> <span class="n">cover</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">100%</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="c">/*Personnaliser le logo */</span>
|
|||
|
<span class="nf">#ynh-logo</span> <span class="p">{</span>
|
|||
|
<span class="nl">z-index</span><span class="p">:</span> <span class="m">10</span><span class="p">;</span>
|
|||
|
<span class="nl">background-image</span><span class="p">:</span> <span class="sx">url("yann.png")</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Puis ajouter en fin du fichier</p>
|
|||
|
|
|||
|
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><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/lettre-y-70x85.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>
|
|||
|
|
|||
|
<span class="c">/*
|
|||
|
===============================================================================
|
|||
|
extra CSS rules to customize the YunoHost user portal and
|
|||
|
can be used to customize app tiles, buttons, etc...
|
|||
|
===============================================================================
|
|||
|
*/</span>
|
|||
|
|
|||
|
<span class="nc">.bluebg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#3498DB</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.bluebg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.bluebg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.bluebg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.bluebg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#16527A</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.purplebg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#9B59B6</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.purplebg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.purplebg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.purplebg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.purplebg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#532C64</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.redbg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#E74C3C</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.redbg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.redbg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.redbg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.redbg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#921E12</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.orangebg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#F39C12</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.orangebg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.orangebg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.orangebg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.orangebg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#7F5006</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.greenbg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#2ECC71</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.greenbg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.greenbg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.greenbg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.greenbg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#176437</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.darkbluebg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#34495E</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.darkbluebg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.darkbluebg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.darkbluebg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.darkbluebg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#07090C</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.lightbluebg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#6A93D4</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.lightbluebg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightbluebg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightbluebg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightbluebg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#2B5394</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.yellowbg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#F1C40F</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.yellowbg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.yellowbg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.yellowbg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.yellowbg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#796307</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
|
|||
|
<span class="nc">.lightpinkbg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#F76F87</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.lightpinkbg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightpinkbg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightpinkbg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightpinkbg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#DA0C31</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="c">/* Following colors are not used yet */</span>
|
|||
|
<span class="nc">.pinkbg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#D66D92</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.pinkbg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.pinkbg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.pinkbg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.pinkbg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#992B52</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.turquoisebg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#1ABC9C</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.turquoisebg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.turquoisebg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.turquoisebg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.turquoisebg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#0B4C3F</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.lightyellow</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#FFC973</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.lightyellow</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightyellow</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightyellow</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightyellow</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#F39500</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.lightgreen</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#B5F36D</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.lightgreen</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightgreen</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightgreen</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.lightgreen</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#77CF11</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.purpledarkbg</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#8E44AD</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nc">.purpledarkbg</span><span class="nd">:hover:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.purpledarkbg</span><span class="nd">:focus:after</span><span class="o">,</span>
|
|||
|
<span class="nc">.purpledarkbg</span><span class="nd">:hover:before</span><span class="o">,</span>
|
|||
|
<span class="nc">.purpledarkbg</span><span class="nd">:focus:before</span> <span class="p">{</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#432051</span><span class="cp">!important</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Personnaliser le logo en modifiant également le fichier <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/themes/yako/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="nl">background-image</span><span class="p">:</span> <span class="sx">url("../../img/yann-logo.png")</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Activer le thème dans le fichier <code class="language-plaintext highlighter-rouge">/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">"yako"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="p">}</span><span class="w">
|
|||
|
</span></code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer le fichier <code class="language-plaintext highlighter-rouge">/usr/share/ssowat/portal/assets/themes/yako/custom_portal.js</code></p>
|
|||
|
|
|||
|
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*
|
|||
|
===============================================================================
|
|||
|
This JS file may be used to customize the YunoHost user portal *and* also
|
|||
|
will be loaded in all app pages if the app nginx's conf does include the
|
|||
|
appropriate snippet.
|
|||
|
|
|||
|
You can monkeypatch init_portal (loading of the user portal) and
|
|||
|
init_portal_button_and_overlay (loading of the button and overlay...) to do
|
|||
|
custom stuff
|
|||
|
===============================================================================
|
|||
|
*/</span>
|
|||
|
|
|||
|
<span class="kd">var</span> <span class="nx">app_tile_colors</span> <span class="o">=</span> <span class="p">[</span><span class="dl">'</span><span class="s1">redbg</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">purpledarkbg</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">darkbluebg</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">orangebg</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">greenbg</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">yellowbg</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">lightpinkbg</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">pinkbg</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">turquoisebg</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">lightbluebg</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">bluebg</span><span class="dl">'</span><span class="p">];</span>
|
|||
|
|
|||
|
<span class="kd">function</span> <span class="nf">set_app_tile_style</span><span class="p">(</span><span class="nx">el</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="c1">// Select a color value from the App label</span>
|
|||
|
<span class="nx">randomColorNumber</span> <span class="o">=</span> <span class="nf">parseInt</span><span class="p">(</span><span class="nx">el</span><span class="p">.</span><span class="nx">textContent</span><span class="p">,</span> <span class="mi">36</span><span class="p">)</span> <span class="o">%</span> <span class="nx">app_tile_colors</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
|
|||
|
<span class="c1">// Add color class.</span>
|
|||
|
<span class="nx">el</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="nx">app_tile_colors</span><span class="p">[</span><span class="nx">randomColorNumber</span><span class="p">]);</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="c1">// Monkeypatch init_portal to customize the app tile style</span>
|
|||
|
<span class="nx">init_portal_original</span> <span class="o">=</span> <span class="nx">init_portal</span><span class="p">;</span>
|
|||
|
<span class="nx">init_portal</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="nf">init_portal_original</span><span class="p">();</span>
|
|||
|
<span class="nb">Array</span><span class="p">.</span><span class="nf">each</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nf">getElementsByClassName</span><span class="p">(</span><span class="dl">"</span><span class="s2">app-tile</span><span class="dl">"</span><span class="p">),</span> <span class="nx">set_app_tile_style</span><span class="p">);</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="cm">/*
|
|||
|
* Monkey patching example to do custom stuff when loading inside an app
|
|||
|
*
|
|||
|
init_portal_button_and_overlay_original = init_portal_button_and_overlay;
|
|||
|
init_portal_button_and_overlay = function()
|
|||
|
{
|
|||
|
init_portal_button_and_overlay_original();
|
|||
|
// Custom stuff to do when loading inside an app
|
|||
|
}
|
|||
|
*/</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><img src="/images/xoyaz-yunohost-theme-yann-1.png" alt="" width="600" /><br />
|
|||
|
<img src="/images/xoyaz-yunohost-theme-yann-2.png" alt="" width="600" /></p>
|
|||
|
|
|||
|
<h4 id="openssh-clé-et-script">OpenSSH, clé et script</h4>
|
|||
|
|
|||
|
<p><img src="/images/openssh-logo.png" alt="OpenSSH" height="70" /><br />
|
|||
|
<u>sur l'ordinateur de bureau</u>
|
|||
|
Générer une paire de clé curve25519-sha256 (ECDH avec Curve25519 et SHA2) nommé <strong>time4vps</strong> pour une liaison SSH avec le serveur KVM.</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/time4vps
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Envoyer les clés publiques sur le serveur KVM</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-copy-id -i ~/.ssh/time4vps.pub admin@195.181.242.156
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><u>sur le serveur Yunohost</u>
|
|||
|
On se connecte</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh admin@195.181.242.156
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Sur votre serveur, la modification du fichier de configuration SSH pour désactiver l’authentification par mot de passe est gérée par un paramètre système</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost settings set security.ssh.password_authentication -v no
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier le port SSH</p>
|
|||
|
|
|||
|
<p><em>Pour empêcher les tentatives de connexion SSH par des robots qui analysent Internet à la recherche de tout serveur sur lequel SSH est activé, vous pouvez modifier le port SSH. Ceci est géré par un paramètre système, qui prend en charge la mise à jour de la configuration SSH et Fail2Ban.</em></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost settings set security.ssh.port -v 55156
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Accès depuis le poste distant avec la clé privée</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -p 55156 -i ~/.ssh/time4vps admin@195.181.242.156
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérification niveau de sécurité (intermediate ou modern)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost settings get security.ssh.compatibility
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>La réponse est “modern” qui correspond au niveau le plus élevé</p>
|
|||
|
|
|||
|
<h4 id="journal">Journal</h4>
|
|||
|
|
|||
|
<p>La façon de s’assurer que vous pouvez visualiser tous les messages de journal est d’ajouter l’utilisateur à un groupe existant tel que adm ou systemd-journal.</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="diagnostics-et-erreurs">Diagnostics et erreurs</h3>
|
|||
|
|
|||
|
<h4 id="resolvconf-nest-pas-un-lien">resolv.conf n’est pas un lien</h4>
|
|||
|
|
|||
|
<p>Se connecter en administrateur sur le site web yunohost xoyaz.xyz<br />
|
|||
|
Lancer le diagnostic</p>
|
|||
|
|
|||
|
<p><u>Problème résolution DNS</u><br />
|
|||
|
<img src="/images/xoyaz-yunohost-diag01.png" alt="" /><br />
|
|||
|
<u>Résolution du problème DNS</u><br />
|
|||
|
Sur yunohost debian 11 le fichier de résolution DNS <code class="language-plaintext highlighter-rouge">/etc/resolv.conf</code> pointe sur le fichier <code class="language-plaintext highlighter-rouge">/run/resolvconf/resolv.conf</code> , ce dernier fichier contient <code class="language-plaintext highlighter-rouge">127.0.0.1</code></p>
|
|||
|
|
|||
|
<p>Sur la machine debian 11 TIME4VPS le fichier <code class="language-plaintext highlighter-rouge">/etc/resolv.conf</code> NE POINTE PAS sur le fichier <code class="language-plaintext highlighter-rouge">/run/resolvconf/resolv.conf</code><br />
|
|||
|
Pour régler le problème (en mode su) :</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-f</span> /etc/resolv.conf
|
|||
|
<span class="nb">ln</span> <span class="nt">-s</span> /run/resolvconf/resolv.conf /etc/resolv.conf
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Un redémarrage du serveur est nécessaire pour vérifier si le problème est corrigé<br />
|
|||
|
Relancer le diagnostic<br />
|
|||
|
<img src="/images/xoyaz-yunohost-diag02.png" alt="" /></p>
|
|||
|
|
|||
|
<p class="info">La prise en compte du lien <code class="language-plaintext highlighter-rouge">/etc/resolv.conf</code> sur <code class="language-plaintext highlighter-rouge">/run/resolvconf/resolv.conf</code> n’a été effective que depuis le 23/07/2022.<br />
|
|||
|
Aucune explication dons à surveiller !!!</p>
|
|||
|
|
|||
|
<h4 id="cron-error-debian-11">Cron error debian 11</h4>
|
|||
|
|
|||
|
<p><a href="https://superuser.com/questions/1687511/cron-error-on-debian11-cd-run-parts-report-etc-cron-hourly">Cron error on Debian11 cd / && run-parts –report /etc/cron.hourly</a></p>
|
|||
|
|
|||
|
<p>1951681242156 remplace RANDOM qui provoque une erreur de syntaxe (fichier <code class="language-plaintext highlighter-rouge">/sbin/run-parts</code>)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/sbin/run-parts
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
|
|||
|
|
|||
|
<span class="nv">parameters</span><span class="o">=</span><span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span>
|
|||
|
<span class="nv">ip</span><span class="o">=</span><span class="si">$(</span><span class="nb">hostname</span> <span class="nt">-i</span><span class="si">)</span>
|
|||
|
<span class="c">#RANDOM=${ip//./}</span>
|
|||
|
<span class="nb">test</span> <span class="nt">-z</span> <span class="s2">"</span><span class="k">${</span><span class="nv">parameters</span><span class="p">##*/etc/cron.*</span><span class="k">}</span><span class="s2">"</span> <span class="o">&&</span>
|
|||
|
<span class="nb">sleep</span> <span class="k">$((</span><span class="m">1951681242156</span> <span class="o">%</span> <span class="m">3600</span><span class="k">))</span>
|
|||
|
|
|||
|
<span class="nb">exec</span> /bin/run-parts <span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="ajouter-des-domaines">Ajouter des domaines</h3>
|
|||
|
|
|||
|
<h4 id="yanfinet">yanfi.net</h4>
|
|||
|
|
|||
|
<p>Ajout domaine yanfi.net en utilisant l’administration web</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add yanfi.net
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Lecture configuration dns pour modifier DNS OVH</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain dns-conf yanfi.net
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ajout certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain cert-install yanfi.net --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="cinayeu">cinay.eu</h4>
|
|||
|
|
|||
|
<p>Ajout domaine cinay.eu en utilisant l’administration web</p>
|
|||
|
|
|||
|
<p>Lecture configuration dns pour modifier DNS OVH</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain dns-conf cinay.eu
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ajout certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain cert-install cinay.eu --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p class="info">Tous les messages du type <*@cinay.eu> sont redirigés vers l’adresse <a href="mailto:yann@xoyaz.xyz">yann@xoyaz.xyz</a></p>
|
|||
|
|
|||
|
<h3 id="historique-de-la-ligne-de-commande">Historique de la ligne de commande</h3>
|
|||
|
|
|||
|
<p>Ajoutez la recherche d’historique de la ligne de commande au terminal<br />
|
|||
|
Se connecter en utilisateur debian<br />
|
|||
|
Tapez un début de commande précédent, puis utilisez shift + up (flèche haut) pour rechercher l’historique 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="nginx-modern">nginx “modern”</h3>
|
|||
|
|
|||
|
<p>Par défaut , on est au niveau “intermédiaire” et on va passer en “moderne”</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># par défaut</span>
|
|||
|
<span class="nb">sudo </span>yunohost settings get security.nginx.compatibility
|
|||
|
|
|||
|
intermediate
|
|||
|
<span class="c"># basculer en moderne</span>
|
|||
|
<span class="nb">sudo </span>yunohost settings <span class="nb">set </span>security.nginx.compatibility <span class="nt">-v</span> modern
|
|||
|
|
|||
|
Success! Configuration updated <span class="k">for</span> <span class="s1">'nginx'</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="sauvegardes">Sauvegardes</h2>
|
|||
|
|
|||
|
<p><img src="/images/borg-logo-a.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Au choix, boîte de stockage ou vps debian server</p>
|
|||
|
|
|||
|
<ol>
|
|||
|
<li><a href="/2021/10/04/BorgBackup_Yunohost-Boite_de_stockage.html">BorgBackup Yunohost –> Boîte de stockage</a><br />
|
|||
|
Dépôt borg : <code class="language-plaintext highlighter-rouge">ssh://u277865@u277865.your-storagebox.de:23/./backup/borg/xoyaz_xyz</code></li>
|
|||
|
<li>BorgBackup Yunohost –> ouestyan.fr (HMS serveur 32771 debian bullseye)<br />
|
|||
|
Dépôt borg : <code class="language-plaintext highlighter-rouge">ssh://borg@ouestyan.fr:55178/srv/data/borg-backups/xoyaz_xyz</code></li>
|
|||
|
</ol>
|
|||
|
|
|||
|
<h3 id="borg-backup-sur-boîte-stockage">Borg Backup sur boîte stockage</h3>
|
|||
|
|
|||
|
<p>Installer l’application <strong>Borg Backup</strong> avec l’administration web<br />
|
|||
|
<img src="/images/bx11-001b.png" alt="" width="600" /></p>
|
|||
|
|
|||
|
<p>borg est installé paramétrage pour la boîte de stockage<br />
|
|||
|
<img src="/images/bx11-002.png" alt="" width="600" /><br />
|
|||
|
Dépôt : <code class="language-plaintext highlighter-rouge">ssh://u326239@u326239.your-storagebox.de:23/./backup/borg/xoyaz.xyz</code></p>
|
|||
|
|
|||
|
<p><em>Ajouter la clé publique <code class="language-plaintext highlighter-rouge">ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPuVXP+pUjvedC/htJmKXamAotLESDCRqU0MOoD7vqCA root@422x.l.time4vps.cloud</code> au fichier <strong>authorized_keys</strong> de la boîte de stockage depuis un poste ayant accès à la boîte de stockage</em></p>
|
|||
|
|
|||
|
<p>Gestion par administration web<br />
|
|||
|
<img src="/images/xoyaz-yunohost-012.png" alt="" /></p>
|
|||
|
|
|||
|
<p><strong>Si on utilise un serveur VPS</strong><br />
|
|||
|
Clé publique à ajouter au fichier <code class="language-plaintext highlighter-rouge">/srv/data/borg-backups/.ssh/authorized_keys</code> du serveur ouestyan.fr (VPS HostMyServer)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPuVXP+pUjvedC/htJmKXamAotLESDCRqU0MOoD7vqCA root@422x.l.time4vps.cloud
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="tester-la-configuration-borg">Tester la configuration borg</h4>
|
|||
|
|
|||
|
<p class="info">À cette étape, votre sauvegarde devrait se dérouler à l’heure prévue (tous les jours à 2h20). Notez que la première sauvegarde peut être très longue, car de nombreuses données doivent être copiées via ssh. Les sauvegardes suivantes sont incrémentielles : seules les données nouvellement générées depuis la dernière sauvegarde seront copiées.</p>
|
|||
|
|
|||
|
<p>Si vous voulez tester la configuration correcte de Borg Apps avant l’heure prévue, vous pouvez lancer une sauvegarde manuellement sur le serveur Yunohost xoyaz.xyz :</p>
|
|||
|
|
|||
|
<p>On passe en tmux</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Instance 1</span>
|
|||
|
<span class="nb">sudo</span> <span class="nt">-s</span>
|
|||
|
tmux
|
|||
|
systemctl start borg
|
|||
|
<span class="c"># Ctrl b d pour sortir de la session tmux</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Visualiser les logs en cours</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>journalctl -f -u borg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>A la fin de la sauvegarde borg<br />
|
|||
|
<img src="/images/xoyaz-yunohost-022.png" alt="" /></p>
|
|||
|
|
|||
|
<h4 id="lister-les-sauvegardes">Lister les sauvegardes</h4>
|
|||
|
|
|||
|
<p>Commande à exécuter en mode su</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg list "$(yunohost app setting $app repository)"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Exemple pour le 23 juillet 2022</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_auto_conf-2022-07-23_02:20 Sat, 2022-07-23 02:20:17 [eed9d4c60a9b79e32938bad01a91ae539a3f38727b542721e8ef18d4b86b26c9]
|
|||
|
_auto_data-2022-07-23_02:20 Sat, 2022-07-23 02:20:50 [9ef65e1274d17244cb623f9f887ccf2f5950c02e3b7a434c4ed167cb7aa300e7]
|
|||
|
_auto_borg-2022-07-23_02:21 Sat, 2022-07-23 02:21:06 [6975d92fd0c0a96935781d52a7dbf2be438ca99b6e27cbca31763eb5a065eaaa]
|
|||
|
_auto_calibreweb-2022-07-23_02:21 Sat, 2022-07-23 02:21:38 [0a9eecb5f0d19e2b7abe1877a169222839cca945c3b31a5f56a474bf3b791f7d]
|
|||
|
_auto_gitea-2022-07-23_02:21 Sat, 2022-07-23 02:22:01 [92b35c0bc96ab7b963aedb20c730df6ff8566c1293058839024564a79ce84805]
|
|||
|
_auto_my_webapp-2022-07-23_02:22 Sat, 2022-07-23 02:22:16 [bd233f946d2f683554b538a175e9d44733ce71d8420d6631283ae982e270194d]
|
|||
|
_auto_my_webapp__2-2022-07-23_02:22 Sat, 2022-07-23 02:22:37 [ca54294f79460c4bcdc974741e7c7f574949fc0301ad651635f4bd6224aa1d7f]
|
|||
|
_auto_navidrome-2022-07-23_02:22 Sat, 2022-07-23 02:22:51 [e8340fc57c707325defc0fd44ca69a9cb39244ef48a99b92972010aaf30390b3]
|
|||
|
_auto_nextcloud-2022-07-23_02:24 Sat, 2022-07-23 02:24:04 [6ad06028790a07e3e5de950ae1e9b6d89664a9c0705e9d4ff1f52160595bd936]
|
|||
|
_auto_searx-2022-07-23_02:24 Sat, 2022-07-23 02:24:46 [fd1d833487bcc8c38b1b343381184dad36f3ee19cf860dc1df97a8fbd92fc135]
|
|||
|
_auto_shaarli-2022-07-23_02:25 Sat, 2022-07-23 02:25:42 [03b93cfb4610f4f5f958f2e31d499ae19475046c569b41a37d184a899569c9a3]
|
|||
|
_auto_snappymail-2022-07-23_02:25 Sat, 2022-07-23 02:25:59 [216eef7cf9587d449728fffd726c8d88ba4c5337c36c53eb83b4d6bd733395c9]
|
|||
|
_auto_transmission-2022-07-23_02:26 Sat, 2022-07-23 02:26:32 [a8506771e63a1172e3997b1e0ca2636628fed421804289f931d0dc3653ebb696]
|
|||
|
_auto_ttrss-2022-07-23_02:26 Sat, 2022-07-23 02:26:51 [0f7357cd55b11cf141eb136596acca471cc9703b153b98e32b616f5c2ac69f4e]
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="restaurer-une-application-sauvegardée-par-borg">Restaurer une application sauvegardée par borg</h3>
|
|||
|
|
|||
|
<p><em>Exemple de restauration d’une application yunohost “shaarli”</em></p>
|
|||
|
|
|||
|
<p>Si l’application est installée, il faut obligatoirement la désinstaller</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app remove shaarli
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Lister les sauvegardes sur la boîte de stockage</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Toutes les sauvegardes</span>
|
|||
|
<span class="nv">app</span><span class="o">=</span>borg<span class="p">;</span> <span class="nv">BORG_PASSPHRASE</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>yunohost app setting <span class="nv">$app</span> passphrase<span class="si">)</span><span class="s2">"</span> <span class="nv">BORG_RSH</span><span class="o">=</span><span class="s2">"ssh -i /root/.ssh/id_</span><span class="k">${</span><span class="nv">app</span><span class="k">}</span><span class="s2">_ed25519 -oStrictHostKeyChecking=yes "</span> <span class="se">\</span>
|
|||
|
borg list <span class="nt">--short</span> <span class="s2">"</span><span class="si">$(</span>yunohost app setting <span class="nv">$app</span> repository<span class="si">)</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># les sauvegardes du jour</span>
|
|||
|
<span class="nv">app</span><span class="o">=</span>borg<span class="p">;</span> <span class="nv">BORG_PASSPHRASE</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>yunohost app setting <span class="nv">$app</span> passphrase<span class="si">)</span><span class="s2">"</span> <span class="nv">BORG_RSH</span><span class="o">=</span><span class="s2">"ssh -i /root/.ssh/id_</span><span class="k">${</span><span class="nv">app</span><span class="k">}</span><span class="s2">_ed25519 -oStrictHostKeyChecking=yes "</span> <span class="se">\</span>
|
|||
|
borg list <span class="nt">--short</span> <span class="s2">"</span><span class="si">$(</span>yunohost app setting <span class="nv">$app</span> repository<span class="si">)</span><span class="s2">"</span> | <span class="nb">grep</span> <span class="si">$(</span><span class="nb">date</span> +<span class="s2">"%Y-%m-%d"</span><span class="si">)</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Après avoir relevé le nom de la sauvegarde <code class="language-plaintext highlighter-rouge">_auto_shaarli-2022-12-19_01:50</code>, il faut télécharger le fichier <code class="language-plaintext highlighter-rouge">.tar.gz</code> correspondant dans le dossier local <code class="language-plaintext highlighter-rouge">/home/yunohost.backup/archives/</code></p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">app</span><span class="o">=</span>borg<span class="p">;</span> <span class="nv">BORG_PASSPHRASE</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>yunohost app setting <span class="nv">$app</span> passphrase<span class="si">)</span><span class="s2">"</span> <span class="nv">BORG_RSH</span><span class="o">=</span><span class="s2">"ssh -i /root/.ssh/id_</span><span class="k">${</span><span class="nv">app</span><span class="k">}</span><span class="s2">_ed25519 -oStrictHostKeyChecking=yes "</span> <span class="se">\</span>
|
|||
|
borg export-tar <span class="s2">"</span><span class="si">$(</span>yunohost app setting <span class="nv">$app</span> repository<span class="si">)</span><span class="s2">::_auto_shaarli-2022-12-19_01:50"</span> /home/yunohost.backup/archives/_auto_shaarli-2022-12-19_01:50.tar.gz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Puis lancer la commande de restauration et patienter</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost backup restore _auto_shaarli-2022-12-19_01:50.tar.gz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="applications">Applications</h2>
|
|||
|
|
|||
|
<h3 id="mises-à-jour-automatique">Mises à jour automatique</h3>
|
|||
|
|
|||
|
<p><em>Unattended_upgrades est un outil qui permet de télécharger et installer les mises à jour de sécurité automatiquement et sans surveillance, en prenant soin de n’installer que les paquets provenant de la source APT configurée, et en vérifiant les invites dpkg concernant les modifications du fichier de configuration. Apticron est un simple script qui envoie des courriels sur les mises à jour de paquets en attente comme les mises à jour de sécurité, en gérant correctement les paquets en attente.</em></p>
|
|||
|
|
|||
|
<p>Installation</p>
|
|||
|
|
|||
|
<p><img src="/images/majauto01.png" alt="" /></p>
|
|||
|
|
|||
|
<p><img src="/images/majauto02.png" alt="" /></p>
|
|||
|
|
|||
|
<h3 id="nextcloud">Nextcloud</h3>
|
|||
|
|
|||
|
<p><img src="/images/nextcloud_logo.png" alt="" width="70" /></p>
|
|||
|
|
|||
|
<p><strong>cloud.xoyaz.xyz</strong></p>
|
|||
|
|
|||
|
<p>Ajout domaine cloud.xoyaz.xyz en utilisant l’administration web</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost domain add cloud.xoyaz.xyz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ajout certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost domain cert-install cloud.xoyaz.xyz --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Mise à niveau nextcloud hub 3 (version 25) le 21 Octobre 2022</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app upgrade nextcloud -u https://github.com/YunoHost-Apps/nextcloud_ynh/tree/testing --debug
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="paramétrage-nextcloud-v25">Paramétrage Nextcloud v25+</h4>
|
|||
|
|
|||
|
<p><em>Nextcloud de base v25+ est installé</em></p>
|
|||
|
|
|||
|
<p>On se connecte en administrateur sur nextcloud <br />
|
|||
|
Cliquer sur l’icône utilisateur en haut à droite de l’écran et sur <strong>Paramètres d’administration</strong><br />
|
|||
|
<img src="/images/nextcloud_hub001.png" alt="" width="300" /><br />
|
|||
|
<img src="/images/nextcloud_hub001a.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Une vérification est faite sur <strong>Vue d’ensemble</strong> dans la rubrique <strong>Administration</strong><br />
|
|||
|
<img src="/images/nextcloud_hub002.png" alt="" /></p>
|
|||
|
|
|||
|
<p>clic sur <strong>Apparence et accessibilité</strong> dans la rubrique <strong>Personnel</strong><br />
|
|||
|
Sélectionner <strong>Thème sombre</strong> <br />
|
|||
|
<img src="/images/nextcloud_hub003.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Arrière-plan<br />
|
|||
|
<img src="/images/nextcloud_hub004.png" alt="" /></p>
|
|||
|
|
|||
|
<h4 id="nextcloud-calendrier-et-contacts">Nextcloud calendrier et contacts</h4>
|
|||
|
|
|||
|
<p>Cliquer sur l’icône utilisateur en haut à droite de l’écran et sur <strong>+ Applications</strong><br />
|
|||
|
On active les applications <strong>Calendar</strong> et <strong>Contacts</strong></p>
|
|||
|
|
|||
|
<h4 id="collabora-online-inactif">Collabora Online (INACTIF)</h4>
|
|||
|
|
|||
|
<p><img src="/images/collabora_logo.png" alt="" width="70" /></p>
|
|||
|
|
|||
|
<p><em>Collabora est une suite bureautique en ligne basée sur LibreOffice et utilisable avec Nextcloud ou ownCloud. Elle permet d’éditer des documents textes, des tableaux, des diaporamas. L’édition en ligne peut se faire en simultanée et permet d’exporter et d’imprimer des documents grâce au format PDF généré.</em></p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>Affichez et modifiez des documents texte, des feuilles de calcul, des présentations, etc.</li>
|
|||
|
<li>Fonctionnalités d’édition collaborative</li>
|
|||
|
<li>Fonctionne dans n’importe quel navigateur moderne - aucun plugin nécessaire</li>
|
|||
|
<li>Conservation de la mise en page et de la mise en forme des documents</li>
|
|||
|
<li>documents texte (odt, docx, doc…)</li>
|
|||
|
<li>des tableurs (ods, xlsx, xls…)</li>
|
|||
|
<li>présentations (odp, pptx, ppt…)</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Ajout domaine <strong>bora.xoyaz.xyz</strong> en utilisant l’administration web<br />
|
|||
|
Ajout certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost domain cert-install bora.xoyaz.xyz --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installation application “Collabora Online” via l’administration web
|
|||
|
<img src="/images/collaboraonline02.png" alt="" /><br />
|
|||
|
<img src="/images/collaboraonline03.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Domaine : bora.xoyaz.xyz<br />
|
|||
|
Mot de passe admin :xxxxxx<br />
|
|||
|
Domaine nextcloud: cloud.xoyaz.xyz</p>
|
|||
|
|
|||
|
<p>Pour une connexion à Nextcloud, activer l’application <strong>Nextcloud Office</strong> dans Nextcloud et configurer avec le domaine de votre installation Collabora.<br />
|
|||
|
Activer <strong>Nextcloud Office</strong> ,clic sur l’icône utilisateur en haut à droite de l’écran , <strong>+ Applications</strong> et <strong>Pack d’applications</strong> <br />
|
|||
|
<img src="/images/nextcloud_hub006.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Cliquer sur l’icône utilisateur en haut à droite de l’écran et sur <strong>Administration settings</strong><br />
|
|||
|
puis sur <strong>Nextcloud Office</strong> dans la rubrique <strong>Administration</strong><br />
|
|||
|
<img src="/images/xoyaz-collabora-1.png" alt="" /><br />
|
|||
|
Le serveur <strong>Collabora Online</strong> est accessible à l’adresse <a href="https://bora.xoyaz.xyz">https://bora.xoyaz.xyz</a></p>
|
|||
|
|
|||
|
<p>La liste d’autorisation pour les demandes WOPI n’est pas configurée<br />
|
|||
|
<img src="/images/xoyaz-collabora-2.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Relever les adresses ipv4 et ipv6 du serveur bora.xoyaz.xyz <br />
|
|||
|
<code class="language-plaintext highlighter-rouge">195.181.242.156/32, 195.181.242.156/32, 2a02:7b40:c3b5:f29c::1/128</code></p>
|
|||
|
|
|||
|
<p>les ajouter à <strong>Allow list for WOPI requests</strong> de <strong>Paramètres avancés</strong><br />
|
|||
|
<img src="/images/xoyaz-collabora-3.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Il existe plusieurs applications <strong>Collabora Online</strong>. Assurez-vous de <code class="language-plaintext warning highlighter-rouge">ne pas installer les applications "Collabora Online - Built-in CODE server"</code>, qui sont une version allégée de ce package Collabora.</p>
|
|||
|
|
|||
|
<p>Exemple ouverture d’un fichier docx avec collabora sur nextcloud<br />
|
|||
|
<img src="/images/xoyaz-collabora01.png" alt="" /></p>
|
|||
|
|
|||
|
<h3 id="onlyoffice">OnlyOffice</h3>
|
|||
|
|
|||
|
<p><img src="/images/onlyoffice-logo.png" alt="" height="100" /><br />
|
|||
|
<em>installer OnlyOffice rapidement et simplement sur un serveur YunoHost</em><br />
|
|||
|
<a href="/2023/08/19/OnlyOffice_pour_YunoHost.html">OnlyOffice YunoHost, Nextcloud et Archlinux</a></p>
|
|||
|
|
|||
|
<h3 id="freshrss-inactif">FreshRSS (INACTIF)</h3>
|
|||
|
|
|||
|
<h4 id="créer-domaine-rssxoyazxyz">Créer domaine rss.xoyaz.xyz</h4>
|
|||
|
|
|||
|
<p>par l’administration web</p>
|
|||
|
|
|||
|
<p><img src="/images/freshrss_logo.png" alt="" height="50px" /></p>
|
|||
|
|
|||
|
<h4 id="installation-par-administration-web">Installation par administration web</h4>
|
|||
|
|
|||
|
<p><img src="/images/freshrss008.png" alt="" /></p>
|
|||
|
|
|||
|
<h4 id="paramétrage-api">Paramétrage API</h4>
|
|||
|
|
|||
|
<p>Il faut mettre un mot depasse API qui peut être identique à un utilisateur<br />
|
|||
|
Tester par le lien <a href="https://rss.xoyaz.xyz/api/">https://rss.xoyaz.xyz/api/</a><br />
|
|||
|
<img src="/images/freshrss009.png" alt="" /></p>
|
|||
|
|
|||
|
<h4 id="application-android-easyrss">Application android EasyRSS</h4>
|
|||
|
|
|||
|
<p>Dans l’application, 3 paramétres</p>
|
|||
|
|
|||
|
<ol>
|
|||
|
<li>URL : https://rss.xoyaz.xyz/api/greader.php</li>
|
|||
|
<li>Utilisateur</li>
|
|||
|
<li>Mot de passe API</li>
|
|||
|
</ol>
|
|||
|
|
|||
|
<h3 id="tiny-tiny-rss">Tiny Tiny RSS</h3>
|
|||
|
|
|||
|
<p><img src="/images/ttrss-logo-a.png" alt="image" width="50px" /></p>
|
|||
|
|
|||
|
<h4 id="domaine-rssxoyazxyz">Domaine rss.xoyaz.xyz</h4>
|
|||
|
|
|||
|
<p>Ajout domaine et certificats rss.xoyaz.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add rss.xoyaz.xyz
|
|||
|
yunohost domain cert install rss.xoyaz.xyz --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[...]
|
|||
|
Success! Configuration updated for 'nginx'
|
|||
|
Success! Let's Encrypt certificate now installed for the domain 'rss.xoyaz.xyz'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Paramétrage en mode administration web, emails sortants et entrants à Non <br />
|
|||
|
<img src="/images/xoyaz-yunohost-003.png" alt="" /></p>
|
|||
|
|
|||
|
<h4 id="installer-tiny-tiny-rss">Installer Tiny Tiny RSS</h4>
|
|||
|
|
|||
|
<p>A-Installation en ligne de commande</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app install https://github.com/YunoHost-Apps/ttrss_ynh/tree/testing
|
|||
|
</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 [xoyaz.xyz | rss.xoyaz.xyz]: rss.xoyaz.xyz
|
|||
|
Choose the URL path (after the domain) where this app should be installed: /
|
|||
|
Should this app be exposed to anonymous visitors? [yes | no]: yes
|
|||
|
[...]
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>B-Installation via admin web<br />
|
|||
|
<img src="/images/ttrss-web-install.png" alt="" /><br />
|
|||
|
<img src="/images/ttrss-web-install01.png" alt="" /><br />
|
|||
|
<img src="/images/ttrss-web-install02.png" alt="" /></p>
|
|||
|
|
|||
|
<h4 id="authentification-par-certificat-client">Authentification par certificat client</h4>
|
|||
|
|
|||
|
<p><img src="/images/certificat-a.png" alt="image" width="80px" /></p>
|
|||
|
|
|||
|
<p><a href="/2022/05/13/Mettre_en_place_et_configurer_une_autorite_de_certification_AC_avec_Easy-RSA.html">Comment mettre en place et configurer une autorité de certification (AC) avec Easy-RSA</a></p>
|
|||
|
|
|||
|
<p>Autorité de certification yako /usr/local/share/ca-certificates/ac-yako.crt , mise à jour par <code class="language-plaintext highlighter-rouge">update-ca-certificates</code></p>
|
|||
|
|
|||
|
<p>Les certificats sous <code class="language-plaintext highlighter-rouge">/etc/ssl/certs/</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>lrwxrwxrwx 1 root root 44 Jul 12 12:03 ac-yako.pem -> /usr/local/share/ca-certificates/ac-yako.crt
|
|||
|
lrwxrwxrwx 1 root root 11 Jul 12 12:03 b93a0109.0 -> ac-yako.pem
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le certificat client suffixe <strong>pfx</strong> sera importé dans firefox et chrome</p>
|
|||
|
|
|||
|
<p>Exemple avec yannick.pfx (Le mot de passe pour l’importation est exigé)<br />
|
|||
|
<img src="/images/certificat-client-firefox-a.png" alt="" /> <br />
|
|||
|
<img src="/images/certificat-client-firefox-b.png" alt="" /></p>
|
|||
|
|
|||
|
<p><a href="/2023/07/13/Tiny-Tiny-RSS_ttrss.html#authentification-par-certificat-client">Tiny Tiny RSS (ttrss) authentification par certificat client</a></p>
|
|||
|
|
|||
|
<h3 id="sites-static-cartes-diceware">Sites static, cartes, diceware</h3>
|
|||
|
|
|||
|
<h4 id="création-domaine-staticxoyazxyz">Création domaine static.xoyaz.xyz</h4>
|
|||
|
|
|||
|
<ol>
|
|||
|
<li>Ouvrir yunohost en mode administrateur</li>
|
|||
|
<li>Créer le domaine static.xoyaz.xyz</li>
|
|||
|
<li>Emails Entrants/Sortants à Non</li>
|
|||
|
<li>Certificat Let’s Encrypt<br />
|
|||
|
<img src="/images/static_xoyize01.png" alt="" /><br />
|
|||
|
<img src="/images/static_xoyize02.png" alt="" /></li>
|
|||
|
</ol>
|
|||
|
|
|||
|
<h4 id="my-webapp">My WebApp</h4>
|
|||
|
|
|||
|
<p><img src="/images/webapp_xoyize00.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Interface administrateur: Applications → Catalogue :My Webapp<br />
|
|||
|
<img src="/images/webapp_xoyize01.png" alt="" /><br />
|
|||
|
REMPLACER static.xoyize.xyz PAR static.xoyaz.xyz</p>
|
|||
|
|
|||
|
<p><img src="/images/webapp_xoyize02.png" alt="" width="400" /></p>
|
|||
|
|
|||
|
<p>Vérifications<br />
|
|||
|
<img src="/images/webapp_xoyaz01.png" alt="" /><br />
|
|||
|
<img src="/images/webapp_xoyaz02.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Le dossier <strong>/home/yunohost.multimedia/share/Divers/static/</strong> contient le site statique qui est issu d’une synchronisation d’un conteneur debian sur un ordinateur archlinux avec jekyll comme générateur</p>
|
|||
|
|
|||
|
<p>En admin su</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-rf</span> /var/www/my_webapp/www/ <span class="c"># supprimer dossier www web par défaut </span>
|
|||
|
<span class="nb">ln</span> <span class="nt">-s</span> /home/yunohost.multimedia/share/Divers/static /var/www/my_webapp/www <span class="c"># lien my_webapp</span>
|
|||
|
|
|||
|
<span class="nb">ln</span> <span class="nt">-s</span> /home/yunohost.multimedia/share/Divers/diceware /var/www/my_webapp/www/diceware
|
|||
|
<span class="nb">ln</span> <span class="nt">-s</span> /home/yunohost.multimedia/share/Divers/osm-new /var/www/my_webapp/www/cartes
|
|||
|
<span class="nb">ln</span> <span class="nt">-s</span> /home/yunohost.multimedia/share/Divers/vps /var/www/my_webapp/www/extra
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Visiter les liens:<br />
|
|||
|
<a href="https://static.xoyaz.xyz">https://static.xoyaz.xyz</a><br />
|
|||
|
<a href="https://static.xoyaz.xyz/cartes">https://static.xoyaz.xyz/cartes</a><br />
|
|||
|
<a href="https://static.xoyaz.xyz/diceware">https://static.xoyaz.xyz/diceware</a><br />
|
|||
|
<a href="https://static.xoyaz.xyz/extra">https://static.xoyaz.xyz/extra</a></p>
|
|||
|
|
|||
|
<h3 id="gitea-giteaxoyazxyz">Gitea gitea.xoyaz.xyz</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.xoyaz.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost domain add gitea.xoyaz.xyz
|
|||
|
sudo yunohost domain cert-install gitea.xoyaz.xyz --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Paramétrage en mode administration web, emails sortants et entrants à Non <br />
|
|||
|
<img src="/images/xoyaz-yunohost-004.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Installation à partir de github</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app install -l gitea https://github.com/YunoHost-Apps/gitea_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 [xoyaz.xyz | gitea.xoyaz.xyz | rss.xoyaz.xyz | searx.x
|
|||
|
oyaz.xyz | static.xoyaz.xyz]: gitea.xoyaz.xyz
|
|||
|
Choose the URL path (after the domain) where this app should be installed: /
|
|||
|
Choose an administrator user for this app [yann]: yann
|
|||
|
Should this app be exposed to anonymous visitors? [yes | no]: yes
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Paramétrage gitea<br />
|
|||
|
<img src="/images/nextcloud_xoyaz.xyz09.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Modifier le paramétrage<br />
|
|||
|
<strong>Compte</strong><br />
|
|||
|
<img src="/images/nextcloud_xoyaz.xyz10.png" alt="" /><br />
|
|||
|
<strong>Profil public</strong>, mise à jour avatar<br />
|
|||
|
<img src="/images/nextcloud_xoyaz.xyz11.png" alt="" /></p>
|
|||
|
|
|||
|
<h3 id="snappymail-webmailxoyazxyz">SnappyMail webmail.xoyaz.xyz</h3>
|
|||
|
|
|||
|
<p><img src="/images/logo-snappymail.png" alt="" height="80" /><br />
|
|||
|
<em>Client de messagerie Web simple, moderne, léger et rapide. La version radicalement améliorée et sécurisée de RainLoop Webmail Community edition.</em></p>
|
|||
|
|
|||
|
<p>Création domaine webmail.xoyaz.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost domain add webmail.xoyaz.xyz
|
|||
|
sudo yunohost domain cert-install webmail.xoyaz.xyz --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Configurer le domaine pour supprimer la gestion des messages entrants et sortants</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain config set webmail.xoyaz.xyz -a "mail_in=0&mail_out=0"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>========================================
|
|||
|
>>>> Feature
|
|||
|
========================================
|
|||
|
Default app [_none | gitea | my_webapp | nextcloud | searx | snappymail | transmission | ttrss]: _none
|
|||
|
Warning: So far, enabling/disabling mail or XMPP features only impact the recommended and automatic DNS configuration, not system configurations!
|
|||
|
Instant messaging (XMPP) [yes | no]: no
|
|||
|
|
|||
|
========================================
|
|||
|
>>>> Dns
|
|||
|
========================================
|
|||
|
Info: This domain is a subdomain of xoyaz.xyz. DNS registrar configuration should be managed in webmail.xoyaz.xyz's configuration panel.
|
|||
|
Info: Saving the new configuration...
|
|||
|
Success! Config updated as expected
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérification</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain config get webmail.xoyaz.xyz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dns.registrar.registrar:
|
|||
|
ask: This domain is a subdomain of xoyaz.xyz. DNS registrar configuration should be managed in webmail.xoyaz.xyz's configuration panel.
|
|||
|
value: parent_domain
|
|||
|
feature.app.default_app:
|
|||
|
ask: Default app
|
|||
|
value: _none
|
|||
|
feature.mail.features_disclaimer:
|
|||
|
ask: So far, enabling/disabling mail or XMPP features only impact the recommended and automatic DNS configuration, not system configurations!
|
|||
|
feature.mail.mail_in:
|
|||
|
ask: Incoming emails
|
|||
|
value: no
|
|||
|
feature.mail.mail_out:
|
|||
|
ask: Outgoing emails
|
|||
|
value: no
|
|||
|
feature.xmpp.xmpp:
|
|||
|
ask: Instant messaging (XMPP)
|
|||
|
value: no
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer application snappymail</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost app install https://github.com/YunoHost-Apps/snappymail_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 [xoyaz.xyz | gitea.xoyaz.xyz | rss.xoyaz.xyz | searx.xoyaz.xyz | stat
|
|||
|
ic.xoyaz.xyz | webmail.xoyaz.xyz]: webmail.xoyaz.xyz
|
|||
|
Choose the URL path (after the domain) where this app should be installed: /
|
|||
|
Should this app be exposed to anonymous visitors? [yes | no]: yes
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le wiki <a href="https://github.com/the-djmaze/snappymail/wiki">https://github.com/the-djmaze/snappymail/wiki</a></p>
|
|||
|
|
|||
|
<h4 id="administration">Administration</h4>
|
|||
|
|
|||
|
<p>Ouvrez l’interface utilisateur admin <a href="https://webmail.xoyaz.xyz/?admin">https://webmail.xoyaz.xyz/?admin</a> pour configurer les paramètres de votre serveur de messagerie. Connectez-vous avec l’utilisateur “admin” et le mot de passe du fichier <code class="language-plaintext highlighter-rouge">/var/www/snappymail/data/_data_/_default_/admin_password.txt</code>. Si vous avez des problèmes pour appeler l’interface d’administration, essayez en mode privé de votre navigateur. De cette façon, les cookies et autres données en cache des installations précédentes sont ignorés.</p>
|
|||
|
|
|||
|
<p><img src="/images/snappymail01.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Modifier le mot de passe admin et ajouter une clé dans “TOTP code” si authentification à 2 facteurs <br />
|
|||
|
<img src="/images/snappymail02.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Ajouter les nouveaux domaines de messagerie si nécessaire</p>
|
|||
|
|
|||
|
<p>TOTP<br />
|
|||
|
Il faut télécharger l’extension “Two Factor Authentication” qui est dans “Available for installation” et la valider
|
|||
|
<img src="/images/snappymail06.png" alt="" /><br />
|
|||
|
Puis cliquer sur la roue dentelée<br />
|
|||
|
<img src="/images/snappymail07.png" alt="" />{width=”400”}</p>
|
|||
|
|
|||
|
<p>Se déconnecter du mode admin</p>
|
|||
|
|
|||
|
<p>Ouvrir en mode utilisateur <a href="https://webmail.xoyaz.xyz">https://webmail.xoyaz.xyz</a><br />
|
|||
|
<img src="/images/snappymail03.png" alt="" /><br />
|
|||
|
Saisir adresse messagerie et mot de passe</p>
|
|||
|
|
|||
|
<h4 id="ajout-comptes-de-messagerie">Ajout comptes de messagerie</h4>
|
|||
|
|
|||
|
<p>Ajouter un compte de messagerie<br />
|
|||
|
<img src="/images/snappymail04.png" alt="" />{width=”400”}<br />
|
|||
|
<img src="/images/snappymail05.png" alt="" />{width=”400”}</p>
|
|||
|
|
|||
|
<p class="info">Tous les comptes de messagerie sont accessibles par une adresse et mot de passe plus un second facteur d’authentification de type TOTP.</p>
|
|||
|
|
|||
|
<h3 id="shaarli-inactif">Shaarli (INACTIF)</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>e the integrity and security of your system. You should probably NOT install it unless you know w
|
|||
|
hat you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system...
|
|||
|
If you are willing to take that risk anyway, type 'Yes, I understand': Yes, I understand
|
|||
|
Choose the domain where this app should be installed [xoyaz.xyz | gitea.xoyaz.xyz | rss.xoyaz.xyz
|
|||
|
| searx.xoyaz.xyz | static.xoyaz.xyz | webmail.xoyaz.xyz]: xoyaz.xyz
|
|||
|
Choose the URL path (after the domain) where this app should be installed: /shaarli
|
|||
|
Choose an administrator user for this app [yann]: yann
|
|||
|
Choose an administration password for this app: **************************
|
|||
|
Choose a title for your Shaarli instance: Shaarli
|
|||
|
Should this app be exposed to anonymous visitors? [yes | no]: yes
|
|||
|
Info: Installing shaarli...
|
|||
|
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Accès <a href="https://xoyaz.xyz/shaarli">https://xoyaz.xyz/shaarli</a></p>
|
|||
|
|
|||
|
<h3 id="calibre-web-inactif">Calibre web (INACTIF)</h3>
|
|||
|
|
|||
|
<p><img src="/images/Calibre_logo.png" alt="" /></p>
|
|||
|
|
|||
|
<p>En mode su</p>
|
|||
|
|
|||
|
<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 l’enregistrement public des utilisateurs</li>
|
|||
|
<li>Envoi d’eBooks vers des appareils Kindle d’un 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 l’authentification proxy.</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Ajout domaine et certificats ebook.xoyaz.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add ebook.xoyaz.xyz
|
|||
|
yunohost domain cert-install ebook.xoyaz.xyz --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Configurer le domaine pour supprimer la gestion des messages entrants et sortants</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain config set ebook.xoyaz.xyz -a "mail_in=0&mail_out=0"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer l’application <strong>Calibre-web</strong> par l’administration web</p>
|
|||
|
|
|||
|
<p><img src="/images/calibre-web20.png" alt="" /><br />
|
|||
|
<img src="/images/calibre-web21.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Par défaut, le processus de sauvegarde de Yunohost sauvegarde la bibliothèque Calibreweb. Vous pouvez désactiver la sauvegarde de la bibliothèque avec</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app setting calibreweb do_not_backup_data -v 1
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<blockquote>
|
|||
|
<p>Par défaut, la suppression de l’application ne supprimera jamais la bibliothèque.</p>
|
|||
|
</blockquote>
|
|||
|
|
|||
|
<p>La bibliothèque existait avant l’installation de Calibreweb,<br />
|
|||
|
<strong>Le dossier des livres</strong> : <code class="language-plaintext highlighter-rouge">/home/yunohost.multimedia/share/eBook/BiblioCalibre/</code></p>
|
|||
|
|
|||
|
<p>Ouverture du lien https://ebook.xoyaz.xyz<br />
|
|||
|
<img src="/images/calibre-web3.png" alt="" /></p>
|
|||
|
|
|||
|
<p><img src="/images/calibre-web4.png" alt="" /><br />
|
|||
|
Rafraîchir poour afficher la liste importée des utilisateurs LDAP</p>
|
|||
|
|
|||
|
<p><img src="/images/calibre-web5.png" alt="" />
|
|||
|
Le dossier des livres <code class="language-plaintext highlighter-rouge">/home/yunohost.multimedia/share/eBook/BiblioCalibre</code></p>
|
|||
|
|
|||
|
<p><img src="/images/calibre-web7.png" alt="" /></p>
|
|||
|
|
|||
|
<p><img src="/images/calibre-web6.png" alt="" /><br />
|
|||
|
<img src="/images/calibre-web8.png" alt="" /></p>
|
|||
|
|
|||
|
<p><img src="/images/calibre-web9.png" alt="" /></p>
|
|||
|
|
|||
|
<p><strong>Lier le champ “lu” avec calibre-web</strong></p>
|
|||
|
|
|||
|
<p>Se connecter en administrateur sur calibre-web<br />
|
|||
|
<img src="/images/calibre-web-01.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Configuration de l’interface utilisateur → Configuration du mode d’affichage<br />
|
|||
|
<img src="/images/calibre-web-02.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Les livres lus sont cochés</p>
|
|||
|
|
|||
|
<p><strong>Modifications pour un accès en lecture écriture du dossier</strong></p>
|
|||
|
|
|||
|
<p>Ajouter l’utilisateur admin au groupe calibreweb pour les droits lecture/écriture</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo gpasswd -a admin calibreweb
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier le chemin de la base et des données Calibre :</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>/home/yunohost.multimedia/share/eBook/BiblioCalibre</li>
|
|||
|
<li>/home/yunohost.multimedia/share/eBook/CalibreTechnique</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Droits <strong>calibreweb.calibreweb</strong> sur le dossier <code class="language-plaintext highlighter-rouge">/home/yunohost.multimedia/share/eBook</code></p>
|
|||
|
|
|||
|
<h3 id="audio-navidrome-inactif">Audio Navidrome (INACTIF)</h3>
|
|||
|
|
|||
|
<h4 id="domaine-zicxoyazxyz">Domaine zic.xoyaz.xyz</h4>
|
|||
|
|
|||
|
<p>Se connecter an administrateur web</p>
|
|||
|
|
|||
|
<p>Ajout domaine zic.xoyaz.xyz et certificats</p>
|
|||
|
|
|||
|
<p>Avant installation Navidrome désactiver le montage SSHFS du dossier musique</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl stop home-yunohost.multimedia-share-Music-musicyan.mount
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer application Navidrome <br />
|
|||
|
Domaine : zic.xoyaz.xyz
|
|||
|
Chemin : /<br />
|
|||
|
Langue : fr</p>
|
|||
|
|
|||
|
<p>Après installation, aller dans Applications Navidrome</p>
|
|||
|
|
|||
|
<p>Modifier le répertoire de la musique et ajouter le dossier des “playlists” dans le fichier <code class="language-plaintext highlighter-rouge">/var/lib/navidrome/navidrome.toml</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Folder to store application data (DB, cache…)
|
|||
|
DataFolder = "/var/lib/navidrome"
|
|||
|
|
|||
|
# Folder where your music library is stored. Can be read-only
|
|||
|
MusicFolder = "/home/yunohost.multimedia/share/Music/musicyan"
|
|||
|
|
|||
|
# Playlist
|
|||
|
ND_PLAYLISTSPATH = "/home/yunohost.multimedia/share/Music/musicyan/Playlists"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Faire une sauvegarde après modification</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo cp /var/lib/navidrome/navidrome.toml /var/lib/navidrome/navidrome.toml.sav
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Lancer le montage SSHFS du dossier musique</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start home-yunohost.multimedia-share-Music-musicyan.mount
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Redémarrer navidrome</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart navidrome
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ouvrir le lien <a href="https://zic.xoyaz.xyz/">https://zic.xoyaz.xyz/</a> et saisir un identifiant + mot de passe pour le compte administrateur</p>
|
|||
|
|
|||
|
<h2 id="maintenance">Maintenance</h2>
|
|||
|
|
|||
|
<h3 id="php-cli-alternative">PHP cli alternative</h3>
|
|||
|
|
|||
|
<p>Pour changer la version PHP cli par défaut</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo update-alternatives --config php
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>There are 2 choices for the alternative php (providing /usr/bin/php).
|
|||
|
|
|||
|
Selection Path Priority Status
|
|||
|
------------------------------------------------------------
|
|||
|
0 /usr/bin/php8.0 80 auto mode
|
|||
|
1 /usr/bin/php7.4 74 manual mode
|
|||
|
* 2 /usr/bin/php8.0 80 manual mode
|
|||
|
|
|||
|
Press <enter> to keep the current choice[*], or type selection number:
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="sshfs">SSHFS</h3>
|
|||
|
|
|||
|
<p><em>Le système SSHFS est un système de fichiers client, basé sur l’utilitaire FUSE, permettant de monter des répertoires distants, au travers d’une connexion SSH. Ce mécanisme utilise le protocole SFTP qui est un sous-système de SSH et est activé, par défaut, sur la plupart des serveurs ssh.</em></p>
|
|||
|
|
|||
|
<p>On se connecte avec l’utilisateur administrateur <strong>yann</strong></p>
|
|||
|
|
|||
|
<p>Installation</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install sshfs
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Générer une paire de clé curve25519-sha256 (ECDH avec Curve25519 et SHA2) pour une liaison SSH avec le serveur CONTABO yunohost xoyize.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/contabo-xoyize
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ajouter le contenu de la clé publique au fichier <code class="language-plaintext highlighter-rouge">~/.ssh/authorized_keys</code> de l’utilisateur administrateur <strong>yako</strong> du serveur CONTABO yunohost xoyize.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEN5pnqRgNghF5rq8o94FgImL8af2+EkwF7d7M72Hwdu yann@xoyaz.xyz" >> .ssh/authorized_keys
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="partage-musique">Partage musique</h4>
|
|||
|
|
|||
|
<p><em>Monter des systèmes de fichiers distants à l’aide de sshfs et systemd</em></p>
|
|||
|
|
|||
|
<p>Partager le dossier <code class="language-plaintext highlighter-rouge">musicyan</code> du vps distant CONTABO xoyize.xyz avec le dossier <code class="language-plaintext highlighter-rouge">/home/yunohost.multimedia/share/Music/musicyan</code> du vps xoyaz.xyz</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>Le dossier qui va être partagé sur le vps xoyize.xyz : <code class="language-plaintext highlighter-rouge">/home/yunohost.multimedia/share/Music/musicyan/</code></li>
|
|||
|
<li>Le point de montage du partage sur le vps xoyaz.xyz : <code class="language-plaintext highlighter-rouge">/home/yunohost.multimedia/share/Music/musicyan</code></li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Création et droits du dossier sur xoyaz.xyz</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo mkdir</span> /home/yunohost.multimedia/share/Music/musicyan
|
|||
|
<span class="nb">sudo chown </span>1000:users /home/yunohost.multimedia/share/Music/musicyan
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le fichier systemd <code class="language-plaintext highlighter-rouge">.mount</code> doit contenir le nom du point de montage, les barres obliques étant remplacées par des “moins”.</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/home/yunohost.multimedia/share/Music/musicyan --> home-yunohost.multimedia-share-Music-musicyan
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le dossier pour les fichiers unitaires personnalisés de systemd est <code class="language-plaintext highlighter-rouge">/etc/systemd/system</code>.</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/systemd/system/home-yunohost.multimedia-share-Music-musicyan.mount
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
|
|||
|
Description=Mount remote fs with sshfs
|
|||
|
|
|||
|
[Install]
|
|||
|
WantedBy=multi-user.target
|
|||
|
|
|||
|
[Mount]
|
|||
|
What=yako@109.123.254.249:/home/yunohost.multimedia/share/Music/musicyan/
|
|||
|
Where=/home/yunohost.multimedia/share/Music/musicyan
|
|||
|
Type=fuse.sshfs
|
|||
|
Options=_netdev,allow_other,IdentityFile=/home/yann/.ssh/contabo-xoyize,port=55249
|
|||
|
|
|||
|
[Install]
|
|||
|
WantedBy=multi-user.target
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Exécution service</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl daemon-reload
|
|||
|
sudo systemctl start home-yunohost.multimedia-share-Music-musicyan.mount
|
|||
|
sudo systemctl enable home-yunohost.multimedia-share-Music-musicyan.mount
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="redirect---inactif">Redirect - INACTIF</h3>
|
|||
|
|
|||
|
<p>Cette application permet d’intégrée une tuile personalisée dans le portail utilisateur de YunoHost. Les cas d’usage typiques sont:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>redirection 301/302 visible</strong> : avoir une tuile d’app “virtuelle” qui se contente de rediriger vers une autre url ou un site externe</li>
|
|||
|
<li><strong>redirection invisible / reverse-proxy</strong> : créer une tuile pour une application locale écoutant sur un port précis, ou bien un conteneur Docker, ou encore une app hébergée sur une autre machine</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>En terme technique: cette app se contente de rajouter le morceau de configuration NGINX approprié avec soit <code class="language-plaintext highlighter-rouge">redirect</code> ou <code class="language-plaintext highlighter-rouge">proxy_pass</code>, et la tuile YunoHost + configuration SSOwat correspondante.</p>
|
|||
|
|
|||
|
<p><strong>Version incluse :</strong> 1.0.0~ynh5</p>
|
|||
|
|
|||
|
<h4 id="redirection-url">Redirection url</h4>
|
|||
|
|
|||
|
<p>Le client sera redirigé vers une autre URL ou site externe</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><code class="language-plaintext highlighter-rouge">votre-domaine.com -> un-autre-domaine.net</code></li>
|
|||
|
<li><code class="language-plaintext highlighter-rouge">votre-domaine.com/foo -> un-autre-domaine.net/bar</code></li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<h4 id="reverse-proxy">Reverse Proxy</h4>
|
|||
|
|
|||
|
<p>L’adresse du client restera inchangé dans le navigateur. Typiquement utilisé pour intéger dans YunoHost une application installée manuellement.</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><code class="language-plaintext highlighter-rouge">you-domain.com/foo -> http://172.0.0.1:8080/app</code></li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p><strong>IMPORTANT:</strong> il vous faudra peut-être bricoler manuellement <code class="language-plaintext highlighter-rouge">redirect.conf</code> dans la configuration nginx, en fonction de vos besoins.</p>
|
|||
|
|
|||
|
<p><strong>IMPORTANT:</strong> Certaines apps ne supportent pas d’être redirigées depuis un chemin différent à cause du fonctionnement des liens relatifs … Cela signifie que par exemple une app hébergée sur <code class="language-plaintext highlighter-rouge">http://127.0.0.1:5050/app/</code> DOIT être routé sur <code class="language-plaintext highlighter-rouge">http://domaine.tld/app/</code> et PAS http://domaine.tld/unautrechemin/. Par exemple: un conteneur Docker Odoo tourne sur <code class="language-plaintext highlighter-rouge">http://127.0.0.1:8069/</code>. Il ne sera pas capable de fonctionné correctement si il est routé sur <code class="language-plaintext highlighter-rouge">http://domaine.tld/odoo/</code> ! Il faut forcément l’installer à la racine d’un domaine, par exemple <code class="language-plaintext highlighter-rouge">http://odoo.domaine.tld/</code></p>
|
|||
|
|
|||
|
<h3 id="netdata---inactif">NetData - INACTIF</h3>
|
|||
|
|
|||
|
<p><em>NetData est un système de surveillance distribuée des performances et de l’état de santé en temps réel. Il fournit un aperçu inégalé, en temps réel, de tout ce qui se passe sur le système qu’il exécute (y compris les applications telles que les serveurs web et de base de données), à l’aide de tableaux de bord web interactifs modernes.</em></p>
|
|||
|
|
|||
|
<p>Installation par administration web<br />
|
|||
|
<img src="/images/xoyaz-yunohost-016.png" alt="" />
|
|||
|
Cliquer sur <strong>Installer</strong></p>
|
|||
|
|
|||
|
<h3 id="le-portail-des-applications-externes---inactif">Le portail des applications externes - INACTIF</h3>
|
|||
|
|
|||
|
<p>Application : “My Webapp”<br />
|
|||
|
Dossier web : <code class="language-plaintext highlighter-rouge">/var/www/my_webapp__2/www/</code><br />
|
|||
|
<img src="/images/xoyaz-yunohost-019.png" alt="" />{width=”400”}</p>
|
|||
|
|
|||
|
<p>Fichier index.html</p>
|
|||
|
|
|||
|
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><!DOCTYPE html></span>
|
|||
|
<span class="nt"><html></span>
|
|||
|
<span class="nt"><head></span>
|
|||
|
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"UTF-8"</span><span class="nt">></span>
|
|||
|
<span class="nt"><title></span>Divers<span class="nt"></title></span>
|
|||
|
<span class="nt"><meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1.0"</span><span class="nt">></span>
|
|||
|
<span class="nt"><style></span>
|
|||
|
<span class="o">*</span> <span class="p">{</span>
|
|||
|
<span class="nl">box-sizing</span><span class="p">:</span> <span class="n">border-box</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.row</span><span class="nd">::after</span> <span class="p">{</span>
|
|||
|
<span class="nl">content</span><span class="p">:</span> <span class="s1">""</span><span class="p">;</span>
|
|||
|
<span class="nl">clear</span><span class="p">:</span> <span class="nb">both</span><span class="p">;</span>
|
|||
|
<span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="o">[</span><span class="nt">class</span><span class="o">*=</span><span class="s1">"col-"</span><span class="o">]</span> <span class="p">{</span>
|
|||
|
<span class="nl">float</span><span class="p">:</span> <span class="nb">left</span><span class="p">;</span>
|
|||
|
<span class="nl">padding</span><span class="p">:</span> <span class="m">15px</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nt">html</span> <span class="p">{</span>
|
|||
|
<span class="c">/* une seule image, centrée */</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="sx">url(northern_lights_starry_sky_mountains_123432_1920x1080.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="nl">font-family</span><span class="p">:</span> <span class="s1">"Lucida Sans"</span><span class="p">,</span> <span class="nb">sans-serif</span><span class="p">;</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="no">yellow</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.header</span> <span class="p">{</span>
|
|||
|
<span class="nl">background-color</span><span class="p">:</span> <span class="m">#9933cc</span><span class="p">;</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="m">#ffffff</span><span class="p">;</span>
|
|||
|
<span class="nl">padding</span><span class="p">:</span> <span class="m">15px</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.menu</span> <span class="nt">ul</span> <span class="p">{</span>
|
|||
|
<span class="nl">list-style-type</span><span class="p">:</span> <span class="nb">none</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="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.menu</span> <span class="nt">li</span> <span class="p">{</span>
|
|||
|
<span class="nl">padding</span><span class="p">:</span> <span class="m">8px</span><span class="p">;</span>
|
|||
|
<span class="nl">margin-bottom</span><span class="p">:</span> <span class="m">7px</span><span class="p">;</span>
|
|||
|
<span class="nl">background-color</span><span class="p">:</span> <span class="m">#33b5e5</span><span class="p">;</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="m">#ffffff</span><span class="p">;</span>
|
|||
|
<span class="nl">box-shadow</span><span class="p">:</span> <span class="m">0</span> <span class="m">1px</span> <span class="m">3px</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.12</span><span class="p">),</span> <span class="m">0</span> <span class="m">1px</span> <span class="m">2px</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.24</span><span class="p">);</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.menu</span> <span class="nt">li</span><span class="nd">:hover</span> <span class="p">{</span>
|
|||
|
<span class="nl">background-color</span><span class="p">:</span> <span class="m">#0099cc</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.aside</span> <span class="p">{</span>
|
|||
|
<span class="c">/*background-color: #33b5e5;*/</span>
|
|||
|
<span class="nl">padding</span><span class="p">:</span> <span class="m">15px</span><span class="p">;</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="m">#ffffff</span><span class="p">;</span>
|
|||
|
<span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
|
|||
|
<span class="nl">font-size</span><span class="p">:</span> <span class="m">14px</span><span class="p">;</span>
|
|||
|
<span class="nl">box-shadow</span><span class="p">:</span> <span class="m">0</span> <span class="m">1px</span> <span class="m">3px</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.12</span><span class="p">),</span> <span class="m">0</span> <span class="m">1px</span> <span class="m">2px</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.24</span><span class="p">);</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nc">.footer</span> <span class="p">{</span>
|
|||
|
<span class="nl">background-color</span><span class="p">:</span> <span class="m">#0099cc</span><span class="p">;</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="m">#ffffff</span><span class="p">;</span>
|
|||
|
<span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
|
|||
|
<span class="nl">font-size</span><span class="p">:</span> <span class="m">12px</span><span class="p">;</span>
|
|||
|
<span class="nl">padding</span><span class="p">:</span> <span class="m">15px</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="c">/* For desktop: */</span>
|
|||
|
<span class="nc">.col-1</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">8.33%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-2</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">16.66%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-3</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">25%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-4</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">33.33%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-5</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">41.66%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-6</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">50%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-7</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">58.33%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-8</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">66.66%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-9</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">75%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-10</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">83.33%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-11</span> <span class="p">{</span><span class="nl">width</span><span class="p">:</span> <span class="m">91.66%</span><span class="p">;}</span>
|
|||
|
<span class="nc">.col-12</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="k">@media</span> <span class="n">only</span> <span class="n">screen</span> <span class="n">and</span> <span class="p">(</span><span class="n">max-width</span><span class="p">:</span> <span class="m">768px</span><span class="p">)</span> <span class="p">{</span>
|
|||
|
<span class="c">/* For mobile phones: */</span>
|
|||
|
<span class="o">[</span><span class="nt">class</span><span class="o">*=</span><span class="s1">"col-"</span><span class="o">]</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="p">}</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nt">a</span><span class="nd">:link</span><span class="o">,</span> <span class="nt">a</span><span class="nd">:visited</span> <span class="p">{</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
|
|||
|
<span class="nl">font-weight</span><span class="p">:</span> <span class="nb">bold</span><span class="p">;</span>
|
|||
|
<span class="nl">background-color</span><span class="p">:</span> <span class="nb">transparent</span><span class="p">;</span>
|
|||
|
<span class="nl">text-decoration</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nt">a</span><span class="nd">:hover</span><span class="o">,</span> <span class="nt">a</span><span class="nd">:focus</span><span class="o">,</span> <span class="nt">a</span><span class="nd">:active</span> <span class="p">{</span>
|
|||
|
<span class="nl">text-decoration</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="m">#75ff33</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nt">img</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="nb">auto</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nt"></style></span>
|
|||
|
<span class="nt"></head></span>
|
|||
|
<span class="nt"><body></span>
|
|||
|
|
|||
|
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"header"</span><span class="nt">></span>
|
|||
|
<span class="nt"><h1></span>Applications<span class="nt"></h1></span>
|
|||
|
<span class="nt"></div></span>
|
|||
|
|
|||
|
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"row"</span><span class="nt">></span>
|
|||
|
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-3 menu"</span><span class="nt">></span>
|
|||
|
<span class="nt"><ul></span>
|
|||
|
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"diceware"</span><span class="nt">></span>Diceware - Mots de passe à haute entropie<span class="nt"></a></li></span>
|
|||
|
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"cartes"</span><span class="nt">></span>Cartes (Leaflet cartographie).<span class="nt"></a></li></span>
|
|||
|
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"https://static.xoyaz.xyz"</span><span class="nt">></span>Site statique (jekyll)<span class="nt"></a></li></span>
|
|||
|
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"https://ebook.xoyaz.xyz"</span><span class="nt">></span>Calibre Web - Livres<span class="nt"></a></li></span>
|
|||
|
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"https://searx.xoyaz.xyz"</span><span class="nt">></span>Searx - Moteur de recherche<span class="nt"></a></li></span>
|
|||
|
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"https://webmail.xoyaz.xyz"</span><span class="nt">></span>Webmail - messagerie web <span class="nt"></a></li></span>
|
|||
|
<span class="nt"></ul></span>
|
|||
|
<span class="nt"></div></span>
|
|||
|
|
|||
|
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-6"</span><span class="nt">></span>
|
|||
|
<span class="nt"><h1></span>Yunohost<span class="nt"></h1></span>
|
|||
|
<span class="nt"><p></span>Dans cette page on affiche les liens des applications qui ne sont pas visibles dans le <span class="nt"><a</span> <span class="na">href=</span><span class="s">"https://xoyaz.xyz"</span><span class="nt">></span>portail<span class="nt"></a></span> <span class="nt"></p></span>
|
|||
|
<span class="nt"></div></span>
|
|||
|
|
|||
|
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-3 right"</span><span class="nt">></span>
|
|||
|
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"aside"</span><span class="nt">></span>
|
|||
|
<span class="nt"><img</span> <span class="na">src=</span><span class="s">"yunohost-logo_blanc.png"</span> <span class="na">width=</span><span class="s">"200"</span> <span class="na">height=</span><span class="s">"200"</span><span class="nt">></span>
|
|||
|
<span class="nt"></div></span>
|
|||
|
<span class="nt"></div></span>
|
|||
|
<span class="nt"></div></span>
|
|||
|
<span class="c"><!--
|
|||
|
<div class="footer">
|
|||
|
<p>Resize the browser window to see how the content respond to the resizing.</p>
|
|||
|
</div>
|
|||
|
--></span>
|
|||
|
<span class="nt"></body></span>
|
|||
|
<span class="nt"></html></span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Lien <a href="https://xoyaz.xyz/div">https://xoyaz.xyz/div</a><br />
|
|||
|
<img src="/images/xoyaz-yunohost-018.png" alt="" /></p>
|
|||
|
|
|||
|
<h3 id="antivirus-clamav---inactif">Antivirus ClamAV - INACTIF</h3>
|
|||
|
|
|||
|
<p><img src="/images/ClamAVLogo_med.png" alt="" width="150" /><br />
|
|||
|
<em>L’antivirus clamav a été installé suite à une suspicion d’infection du vps avec risque de blocage par l’autorité de gestion TIME4VPS</em></p>
|
|||
|
|
|||
|
<p>Installation et procédures, voir le lien suivant : <a href="/2022/08/19/Linux-Antivirus-ClamAV.html">ClamAV antivirus linux</a></p>
|
|||
|
|
|||
|
<p>Les bases antivirales sont mises à jour tous les 6 heures</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Création du tâche à exécuter en root</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab -e
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>On va scanner à 1h du matin tous les jours le dossier <code class="language-plaintext highlighter-rouge">/home/yunohost.multimedia/share/Divers/static</code> avec une réserve à 15% sur l’utilisation du CPU</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># ClamAV antivirus scan avec utilisation CPU de 15% max </span>
|
|||
|
00 01 <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> <span class="nb">nice</span> <span class="nt">-n</span> 15 clamscan <span class="o">&&</span> clamscan <span class="nt">-ir</span> <span class="nt">-l</span> /var/log/clamav/scan.log /home/yunohost.multimedia/share/Divers/static
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="annexe">ANNEXE</h2>
|
|||
|
|
|||
|
<h3 id="test-de-sécurité">Test de sécurité</h3>
|
|||
|
|
|||
|
<p><a href="https://www.ssllabs.com/ssltest/index.html">Analyse SSL</a> contre le site Web pour trouver le score et la vulnérabilité essentielle.<br />
|
|||
|
<img src="/images/ssllabs-xoyaz.xyz.png" alt="" /></p>
|
|||
|
|
|||
|
<p class="warning">ATTENTION! En mode “modern” , seul <strong>TLS1.3</strong> est autorisé et le “grade” va passer à <strong>A</strong></p>
|
|||
|
|
|||
|
<h3 id="erreurs">Erreurs</h3>
|
|||
|
|
|||
|
<h4 id="erreur-certificat-invalide-port-587">Erreur Certificat invalide (port 587)</h4>
|
|||
|
|
|||
|
<p>Lors de l’envoi d’un message en utilisant le smtp xoyaz.xyz, j’ai une erreur<br />
|
|||
|
<img src="/images/erreur-smtp.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Le certificat SSL est valide<br />
|
|||
|
<img src="/images/erreur-smtp01.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Par contre il n’est pas valide sur le port 587</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>openssl s_client -starttls smtp -showcerts -connect xoyaz.xyz:587 -servername xoyaz.xyz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><img src="/images/erreur-smtp02.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Pour la solution, il faut exécuter le commande suivante sur le serveur</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo postmap -F hash:/etc/postfix/sni
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérification</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>openssl s_client -starttls smtp -showcerts -connect xoyaz.xyz:587 -servername xoyaz.xyz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><img src="/images/erreur-smtp03.png" alt="" /></p>
|
|||
|
|
|||
|
<p>Il faut exécuter la commande <code class="language-plaintext highlighter-rouge">postmap -F hash:/etc/postfix/sni</code> après chaque renouvellement de certificat…</p>
|
|||
|
|
|||
|
<p>YunoHost a été développé dans l’optique de fournir une sécurité maximale tout en restant accessible et facilement installable.</p>
|
|||
|
|
|||
|
<p>Tous les protocoles que YunoHost utilise sont <strong>chiffrés</strong>, les mots de passe ne sont pas stockés en clair, et par défaut chaque utilisateur n’accède qu’à son répertoire personnel.</p>
|
|||
|
|
|||
|
<p>Deux points sont néanmoins importants à noter :</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<p>L’installation d’applications supplémentaires <strong>augmente le nombre de failles</strong> potentielles. Il est donc conseillé de se renseigner sur chacune d’elle <strong>avant l’installation</strong>, d’en comprendre le fonctionnement et juger ainsi l’impact que provoquerait une potentielle attaque. N’installez <strong>que</strong> les applications qui semblent importantes pour votre usage.</p>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p>Le fait que YunoHost soit un logiciel répandu augmente les chances de subir une attaque. Si une faille est découverte, elle peut potentiellement <strong>toucher toutes les instances YunoHost</strong> à un temps donné. Nous nous efforçons de corriger ces failles le plus rapidement possible, pensez donc à <strong>mettre à jour régulièrement</strong> votre système.</p>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>!!!! Si vous avez besoin de conseil, n’hésitez pas à <a href="/help">nous demander</a>.</p>
|
|||
|
|
|||
|
<p>!! [fa=shield /] Pour discuter d’une faille de sécurité, contactez l’<a href="/security_team">équipe sécurité de YunoHost</a>.</p>
|
|||
|
|
|||
|
<h3 id="améliorer-la-sécurité---suggestions">Améliorer la sécurité - SUGGESTIONS</h3>
|
|||
|
|
|||
|
<p>Si votre serveur YunoHost est dans un environnement de production critique ou que vous souhaitez améliorer sa sécurité, il est bon de suivre quelques bonnes pratiques.</p>
|
|||
|
|
|||
|
<p>! <strong>Attention :</strong> l’application des conseils suivants nécessite une connaissance avancée du fonctionnement et de l’administration d’un serveur. Pensez à vous renseigner avant de procéder à cette mise en place.</p>
|
|||
|
|
|||
|
<p>!!!! <strong>Astuce :</strong> Ne fermez jamais votre connexion SSH initiale sans avoir vérifié que vos modifications fonctionnent. Testez vos modifications dans une nouvelle fenêtre ou terminal. Ainsi, vous pourrez défaire vos modifications sans vous retrouver bloqués.</p>
|
|||
|
|
|||
|
<h4 id="authentification-ssh-par-clé">Authentification SSH par clé</h4>
|
|||
|
|
|||
|
<p>Voici un <a href="http://doc.ubuntu-fr.org/ssh#authentification_par_un_systeme_de_cles_publiqueprivee">tutoriel plus détaillé</a>.</p>
|
|||
|
|
|||
|
<p>Par défaut, l’authentification SSH se fait avec le mot de passe d’administration. Il est conseillé de désactiver ce type d’authentification et de le remplacer par un mécanisme de clé de chiffrement.</p>
|
|||
|
|
|||
|
<p><strong>Sur votre ordinateur de bureau :</strong></p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen
|
|||
|
ssh-copy-id <span class="nt">-i</span> ~/.ssh/id_rsa.pub <nom_utilisateur@votre.domaine.tld>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>!!! Si vous avez des problèmes de permissions, donnez à <code class="language-plaintext highlighter-rouge">nom_utilisateur</code> la possession du dossier <code class="language-plaintext highlighter-rouge">~/.ssh</code> avec <code class="language-plaintext highlighter-rouge">chown</code>. Attention, pour des raisons de sécurité, ce dossier doit être en mode 700 !</p>
|
|||
|
|
|||
|
<p>!!! Si vous êtes sur Ubuntu 16.04 vous devez faire <code class="language-plaintext highlighter-rouge">ssh-add</code> pour initialiser l’agent SSH.</p>
|
|||
|
|
|||
|
<p>Entrez le mot de passe d’administration et votre clé publique devrait être copiée sur votre serveur.</p>
|
|||
|
|
|||
|
<p><strong>Sur votre serveur</strong>, l’édition du fichier de configuration SSH pour désactiver l’authentification par mot de passe est gérée par un paramètre système :</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yunohost settings <span class="nb">set </span>security.ssh.password_authentication <span class="nt">-v</span> no
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="modifier-le-port-ssh">Modifier le port SSH</h4>
|
|||
|
|
|||
|
<p>Pour éviter des tentatives de connexion SSH par des robots qui scannent tout Internet pour tenter des connexions SSH avec tout serveur accessible, on peut modifier le port SSH.
|
|||
|
C’est géré par un paramètre système, qui se charge de configurer les services SSH et Fail2Ban.</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yunohost settings <span class="nb">set </span>security.ssh.port <span class="nt">-v</span> <votre_numero_de_port_ssh>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Lors de la prochaine connexion SSH</strong>, vous devrez ajouter le paramètre <code class="language-plaintext highlighter-rouge">-p</code> suivi du port SSH.</p>
|
|||
|
|
|||
|
<p><strong>Exemple</strong>:</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh <span class="nt">-p</span> <votre_numero_de_port_ssh> admin@<votre_serveur_yunohost>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="durcir-la-sécurité-de-la-configuration-des-services">Durcir la sécurité de la configuration des services</h4>
|
|||
|
|
|||
|
<p>La configuration TLS par défaut des services tend à offrir une bonne compatibilité avec les vieux appareils. Vous pouvez régler cette politique pour les services SSH et NGINX. Par défaut, la configuration du NGINX suit la <a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29">recommandation de compatibilité intermédiaire</a> de Mozilla. Vous pouvez choisir de passer à la configuration « moderne » qui utilise des recommandations de sécurité plus récentes, mais qui diminue la compatibilité, ce qui peut poser un problème pour vos utilisateurs et visiteurs qui utilisent de vieux appareils. Plus de détails peuvent être trouvés sur <a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility">cette page</a>.</p>
|
|||
|
|
|||
|
<p>Changer le niveau de compatibilité n’est pas définitif et il est possible de rechanger le paramètre si vous concluez qu’il faut revenir en arrière.</p>
|
|||
|
|
|||
|
<p><strong>Sur votre serveur</strong>, modifiez la politique pour NGINX :</p>
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yunohost settings <span class="nb">set </span>security.nginx.compatibility <span class="nt">-v</span> modern
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Sur votre serveur</strong>, modifiez la politique pour SSH :</p>
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yunohost settings <span class="nb">set </span>security.ssh.compatibility <span class="nt">-v</span> modern
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="désactivation-de-lapi-yunohost">Désactivation de l’API YunoHost</h4>
|
|||
|
|
|||
|
<p>YunoHost est administrable via une <strong>API HTTP</strong>, servie sur le port 6787 par défaut (seulement sur <code class="language-plaintext highlighter-rouge">localhost</code>). Elle permet d’administrer une grande partie de votre serveur, et peut donc être utilisée à des <strong>fins malveillantes</strong>. La meilleure chose à faire si vous êtes habitués à la ligne de commande est de désactiver le service <code class="language-plaintext highlighter-rouge">yunohost-api</code>, et <strong>utiliser la <a href="/commandline">ligne de commande</a></strong> en SSH.</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl disable yunohost-api
|
|||
|
<span class="nb">sudo </span>systemctl stop yunohost-api
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2022-06-08T00: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>
|
|||
|
|
|||
|
 </div>
|
|||
|
-->
|
|||
|
</footer>
|
|||
|
<div class="article__section-navigator clearfix"><div class="previous"><span>PRÉCÉDENT</span><a href="/2022/05/24/BorgBackup_sauvegarde_Home.html">BorgBackup sauvegarde Home</a></div><div class="next"><span>SUIVANT</span><a href="/2022/06/24/Yunohost_Debian_Bullseye_image_de_nuage_Qcow2.html">Qemu/KVM - Virtuel Yunohost ouestyan.xyz (debian 11 image cloud Qcow2)</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} {title}</a> (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>
|
|||
|
|